Merge lp:~xnox/ubuntu/trusty/plymouth/private-upstart-socket into lp:ubuntu/trusty/plymouth
- Trusty (14.04)
- private-upstart-socket
- Merge into trusty
Status: | Merged |
---|---|
Merged at revision: | 1480 |
Proposed branch: | lp:~xnox/ubuntu/trusty/plymouth/private-upstart-socket |
Merge into: | lp:ubuntu/trusty/plymouth |
Diff against target: |
4818 lines (+4385/-150) 21 files modified
.pc/applied-patches (+4/-0) .pc/dont-bail-on-dummy-terms.patch/src/upstart-bridge/plymouth-upstart-bridge.c (+339/-0) .pc/no-print-empty-description.patch/src/upstart-bridge/ply-upstart-monitor.c (+1182/-0) .pc/ubuntu-logo-scale-factor-2.patch/themes/ubuntu-logo/Makefile.am (+23/-0) .pc/ubuntu-logo-scale-factor-2.patch/themes/ubuntu-logo/ubuntu-logo.plymouth.in (+8/-0) .pc/use-upstart-private-socket.patch/src/upstart-bridge/ply-upstart-monitor.c (+1301/-0) debian/changelog (+22/-0) debian/control (+1/-1) debian/patches/dont-bail-on-dummy-terms.patch (+17/-0) debian/patches/no-print-empty-description.patch (+14/-0) debian/patches/series (+4/-0) debian/patches/ubuntu-logo-scale-factor-2.patch (+1202/-0) debian/patches/use-upstart-private-socket.patch (+198/-0) debian/plymouth-theme-ubuntu-logo.postinst (+6/-0) debian/plymouth-theme-ubuntu-logo.prerm (+2/-0) debian/plymouth.plymouth-upstart-bridge.upstart (+5/-2) src/upstart-bridge/ply-upstart-monitor.c (+11/-130) src/upstart-bridge/plymouth-upstart-bridge.c (+3/-1) themes/ubuntu-logo/Makefile.am (+18/-5) themes/ubuntu-logo/ubuntu-logo.plymouth.in (+2/-2) themes/ubuntu-logo/ubuntu-logo.script.in (+23/-9) |
To merge this branch: | bzr merge lp:~xnox/ubuntu/trusty/plymouth/private-upstart-socket |
Related bugs: | |
Related blueprints: |
Boot experience on hidpi displays
(Undefined)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Hunt | Pending | ||
Stéphane Graber | Pending | ||
Colin Watson | Pending | ||
Steve Langasek | Pending | ||
Ubuntu branches | Pending | ||
Review via email: mp+210672@code.launchpad.net |
Commit message
* debian/
system dbus, use private upstart socket in the plymouth-
* debian/
plymouth-
boot.log.
* debian/
plymouth-
terminal, as we can run on those. This makes console-log useful in
lxc-containers and actually contain messages from upstart jobs
starting and stopping.
* debian/
description when dbus returns empty string, and thus stop printing
empty "Starting... done" messages.
* debian/
conditions to stop when plymouth-shutdown finishes.
* Make ubuntu-logo theme support scale factor, provide one plymouth
theme with scale 1 and another with scale 2, until scale factor can be
dynamically detected.
* Mark plymouth-
Description of the change
First this patch series fixes to use upstart private socket, and thus able to start on startup. That was mostly removing code to deal with system-bus, looking up nameowner, and monitoring nameowner changes.
Next I've tried testing plymouth-
This resulted in loads of empty messages, but it was never intended to print empty messages, so i've fixed that (dbus returns empty string, not NULL).
And i've also removed description stanza from the startpar bridge (separate upload) such that one does not get extra messages about startpar bridge firing, for every upstart job that is printed.
One now gets a more complete /var/log/boot.log on more ubuntu configurations.
For HiDPI support, I've tweaked ubuntu-logo theme to support "scalingfactor" for all loaded images/text/layout, and generated one theme with scalingfactor set to 1 (same as current theme) and another one with scalingfactor set to 2 to support highdpi screens via update-
- 1473. By Dimitri John Ledkov
-
system dbus, use private upstart socket in the plymouth-
upstart- bridge.
* debian/patches/ dont-bail- on-dummy- terms.patch: don't bail
plymouth-upstart- bridge if TERM is not set and/or running on a dummy
terminal, as we can run on those. - 1474. By Dimitri John Ledkov
-
* debian/
patches/ no-print- empty-descripti on.patch: do not store
description when dbus returns empty string, and thus stop printing
empty "Starting... done" messages. - 1475. By Dimitri John Ledkov
-
debian/
plymouth. plymouth- upstart- bridge. upstart: update stop on
conditions to stop when plymouth-shutdown finishes. - 1476. By Dimitri John Ledkov
-
empty "Starting... done" messages. LP: #1185560.
- 1477. By Dimitri John Ledkov
-
Make ubuntu-logo theme support scale factor, provide one plymouth
theme with scale 1 and another with scale 2, until scale factor can be
dynamically detected. - 1478. By Dimitri John Ledkov
-
Mark plymouth-
upstart- bridge to respawn. - 1479. By Dimitri John Ledkov
-
Fix up scale-factor-2 patch
- 1480. By Dimitri John Ledkov
-
[ Dimitri John Ledkov ] LP: #1292458
Preview Diff
1 | === modified file '.pc/applied-patches' | |||
2 | --- .pc/applied-patches 2013-12-02 04:53:37 +0000 | |||
3 | +++ .pc/applied-patches 2014-03-14 10:43:52 +0000 | |||
4 | @@ -13,3 +13,7 @@ | |||
5 | 13 | Miscellaneous-fixes-for-compiler-warnings.patch | 13 | Miscellaneous-fixes-for-compiler-warnings.patch |
6 | 14 | autoreconf.patch | 14 | autoreconf.patch |
7 | 15 | details-update-status.patch | 15 | details-update-status.patch |
8 | 16 | use-upstart-private-socket.patch | ||
9 | 17 | dont-bail-on-dummy-terms.patch | ||
10 | 18 | no-print-empty-description.patch | ||
11 | 19 | ubuntu-logo-scale-factor-2.patch | ||
12 | 16 | 20 | ||
13 | === added directory '.pc/dont-bail-on-dummy-terms.patch' | |||
14 | === added directory '.pc/dont-bail-on-dummy-terms.patch/src' | |||
15 | === added directory '.pc/dont-bail-on-dummy-terms.patch/src/upstart-bridge' | |||
16 | === added file '.pc/dont-bail-on-dummy-terms.patch/src/upstart-bridge/plymouth-upstart-bridge.c' | |||
17 | --- .pc/dont-bail-on-dummy-terms.patch/src/upstart-bridge/plymouth-upstart-bridge.c 1970-01-01 00:00:00 +0000 | |||
18 | +++ .pc/dont-bail-on-dummy-terms.patch/src/upstart-bridge/plymouth-upstart-bridge.c 2014-03-14 10:43:52 +0000 | |||
19 | @@ -0,0 +1,339 @@ | |||
20 | 1 | /* plymouth-upstart-bridge.c - bridge Upstart job state changes to Plymouth | ||
21 | 2 | * | ||
22 | 3 | * Copyright (C) 2010, 2011 Canonical Ltd. | ||
23 | 4 | * | ||
24 | 5 | * This program is free software; you can redistribute it and/or modify | ||
25 | 6 | * it under the terms of the GNU General Public License as published by | ||
26 | 7 | * the Free Software Foundation; either version 2, or (at your option) | ||
27 | 8 | * any later version. | ||
28 | 9 | * | ||
29 | 10 | * This program is distributed in the hope that it will be useful, | ||
30 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
31 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
32 | 13 | * GNU General Public License for more details. | ||
33 | 14 | * | ||
34 | 15 | * You should have received a copy of the GNU General Public License | ||
35 | 16 | * along with this program; if not, write to the Free Software | ||
36 | 17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
37 | 18 | * 02111-1307, USA. | ||
38 | 19 | * | ||
39 | 20 | * Written by: Colin Watson <cjwatson@ubuntu.com> | ||
40 | 21 | */ | ||
41 | 22 | #include "config.h" | ||
42 | 23 | |||
43 | 24 | #include <stdbool.h> | ||
44 | 25 | #include <signal.h> | ||
45 | 26 | #include <stdlib.h> | ||
46 | 27 | #include <stdio.h> | ||
47 | 28 | #include <string.h> | ||
48 | 29 | #include <unistd.h> | ||
49 | 30 | |||
50 | 31 | #if defined(HAVE_NCURSESW_TERM_H) | ||
51 | 32 | #include <ncursesw/term.h> | ||
52 | 33 | #elif defined(HAVE_NCURSES_TERM_H) | ||
53 | 34 | #include <ncurses/term.h> | ||
54 | 35 | #else | ||
55 | 36 | #include <term.h> | ||
56 | 37 | #endif | ||
57 | 38 | |||
58 | 39 | #include "ply-boot-client.h" | ||
59 | 40 | #include "ply-command-parser.h" | ||
60 | 41 | #include "ply-event-loop.h" | ||
61 | 42 | #include "ply-logger.h" | ||
62 | 43 | #include "ply-upstart-monitor.h" | ||
63 | 44 | |||
64 | 45 | typedef struct | ||
65 | 46 | { | ||
66 | 47 | ply_event_loop_t *loop; | ||
67 | 48 | ply_boot_client_t *client; | ||
68 | 49 | ply_upstart_monitor_t *upstart; | ||
69 | 50 | ply_command_parser_t *command_parser; | ||
70 | 51 | } state_t; | ||
71 | 52 | |||
72 | 53 | #ifndef TERMINAL_COLOR_RED | ||
73 | 54 | #define TERMINAL_COLOR_RED 1 | ||
74 | 55 | #endif | ||
75 | 56 | |||
76 | 57 | /* We don't care about the difference between "not a string capability" and | ||
77 | 58 | * "cancelled or absent". | ||
78 | 59 | */ | ||
79 | 60 | static const char * | ||
80 | 61 | get_string_capability (const char *name) | ||
81 | 62 | { | ||
82 | 63 | const char *value; | ||
83 | 64 | |||
84 | 65 | value = tigetstr ((char *) name); | ||
85 | 66 | if (value == (const char *) -1) | ||
86 | 67 | value = NULL; | ||
87 | 68 | |||
88 | 69 | return value; | ||
89 | 70 | } | ||
90 | 71 | |||
91 | 72 | static bool | ||
92 | 73 | terminal_ignores_new_line_after_80_chars (void) | ||
93 | 74 | { | ||
94 | 75 | return tigetflag ((char *) "xenl") != 0; | ||
95 | 76 | } | ||
96 | 77 | |||
97 | 78 | static int | ||
98 | 79 | get_number_of_columns (void) | ||
99 | 80 | { | ||
100 | 81 | int number_of_columns; | ||
101 | 82 | |||
102 | 83 | number_of_columns = tigetnum ((char *) "cols"); | ||
103 | 84 | |||
104 | 85 | return number_of_columns; | ||
105 | 86 | } | ||
106 | 87 | |||
107 | 88 | static bool | ||
108 | 89 | can_set_cursor_column (void) | ||
109 | 90 | { | ||
110 | 91 | const char *capability; | ||
111 | 92 | |||
112 | 93 | capability = get_string_capability ("hpa"); | ||
113 | 94 | |||
114 | 95 | return capability != NULL; | ||
115 | 96 | } | ||
116 | 97 | |||
117 | 98 | static void | ||
118 | 99 | set_cursor_column (int column) | ||
119 | 100 | { | ||
120 | 101 | const char *capability; | ||
121 | 102 | const char *terminal_string; | ||
122 | 103 | |||
123 | 104 | capability = get_string_capability ("hpa"); | ||
124 | 105 | terminal_string = tiparm (capability, column); | ||
125 | 106 | fputs (terminal_string, stdout); | ||
126 | 107 | } | ||
127 | 108 | |||
128 | 109 | static bool | ||
129 | 110 | can_set_fg_color (void) | ||
130 | 111 | { | ||
131 | 112 | const char *capability; | ||
132 | 113 | |||
133 | 114 | capability = get_string_capability ("setaf"); | ||
134 | 115 | |||
135 | 116 | return capability != NULL; | ||
136 | 117 | } | ||
137 | 118 | |||
138 | 119 | static void | ||
139 | 120 | set_fg_color (int color) | ||
140 | 121 | { | ||
141 | 122 | const char *capability; | ||
142 | 123 | const char *terminal_string; | ||
143 | 124 | |||
144 | 125 | capability = get_string_capability ("setaf"); | ||
145 | 126 | terminal_string = tiparm (capability, color); | ||
146 | 127 | fputs (terminal_string, stdout); | ||
147 | 128 | } | ||
148 | 129 | |||
149 | 130 | static void | ||
150 | 131 | unset_fg_color (void) | ||
151 | 132 | { | ||
152 | 133 | const char *terminal_string; | ||
153 | 134 | |||
154 | 135 | terminal_string = get_string_capability ("op"); | ||
155 | 136 | |||
156 | 137 | if (terminal_string == NULL) | ||
157 | 138 | return; | ||
158 | 139 | |||
159 | 140 | fputs (terminal_string, stdout); | ||
160 | 141 | } | ||
161 | 142 | |||
162 | 143 | static void | ||
163 | 144 | update_status (state_t *state, | ||
164 | 145 | ply_upstart_monitor_job_properties_t *job, | ||
165 | 146 | ply_upstart_monitor_instance_properties_t *instance, | ||
166 | 147 | const char *action, | ||
167 | 148 | bool is_okay) | ||
168 | 149 | { | ||
169 | 150 | ply_boot_client_update_daemon (state->client, job->name, NULL, NULL, state); | ||
170 | 151 | |||
171 | 152 | if (job->description == NULL) | ||
172 | 153 | return; | ||
173 | 154 | |||
174 | 155 | printf (" * %s%s%s", | ||
175 | 156 | action ? action : "", action ? " " : "", job->description); | ||
176 | 157 | |||
177 | 158 | if (terminal_ignores_new_line_after_80_chars () && can_set_cursor_column ()) | ||
178 | 159 | { | ||
179 | 160 | int number_of_columns, column; | ||
180 | 161 | |||
181 | 162 | number_of_columns = get_number_of_columns (); | ||
182 | 163 | |||
183 | 164 | if (number_of_columns < (int) strlen("[fail]")) | ||
184 | 165 | number_of_columns = 80; | ||
185 | 166 | |||
186 | 167 | column = number_of_columns - strlen ("[fail]") - 1; | ||
187 | 168 | |||
188 | 169 | set_cursor_column (column); | ||
189 | 170 | |||
190 | 171 | if (is_okay) | ||
191 | 172 | puts ("[ OK ]"); | ||
192 | 173 | else | ||
193 | 174 | { | ||
194 | 175 | bool supports_color; | ||
195 | 176 | |||
196 | 177 | supports_color = can_set_fg_color (); | ||
197 | 178 | |||
198 | 179 | fputs ("[", stdout); | ||
199 | 180 | |||
200 | 181 | if (supports_color) | ||
201 | 182 | set_fg_color (TERMINAL_COLOR_RED); | ||
202 | 183 | |||
203 | 184 | fputs ("fail", stdout); | ||
204 | 185 | |||
205 | 186 | if (supports_color) | ||
206 | 187 | unset_fg_color (); | ||
207 | 188 | |||
208 | 189 | puts ("]"); | ||
209 | 190 | } | ||
210 | 191 | } | ||
211 | 192 | else | ||
212 | 193 | { | ||
213 | 194 | if (is_okay) | ||
214 | 195 | puts (" ...done."); | ||
215 | 196 | else | ||
216 | 197 | puts (" ...fail!"); | ||
217 | 198 | } | ||
218 | 199 | } | ||
219 | 200 | |||
220 | 201 | static void | ||
221 | 202 | on_failed (void *data, | ||
222 | 203 | ply_upstart_monitor_job_properties_t *job, | ||
223 | 204 | ply_upstart_monitor_instance_properties_t *instance, | ||
224 | 205 | int status) | ||
225 | 206 | { | ||
226 | 207 | state_t *state = data; | ||
227 | 208 | |||
228 | 209 | if (job->is_task) | ||
229 | 210 | update_status (state, job, instance, NULL, false); | ||
230 | 211 | else | ||
231 | 212 | { | ||
232 | 213 | if (strcmp (instance->goal, "start") == 0) | ||
233 | 214 | update_status (state, job, instance, "Starting", false); | ||
234 | 215 | else if (strcmp (instance->goal, "stop") == 0) | ||
235 | 216 | update_status (state, job, instance, "Stopping", false); | ||
236 | 217 | } | ||
237 | 218 | } | ||
238 | 219 | |||
239 | 220 | static void | ||
240 | 221 | on_state_changed (state_t *state, | ||
241 | 222 | const char *old_state, | ||
242 | 223 | ply_upstart_monitor_job_properties_t *job, | ||
243 | 224 | ply_upstart_monitor_instance_properties_t *instance) | ||
244 | 225 | { | ||
245 | 226 | if (instance->failed) | ||
246 | 227 | return; | ||
247 | 228 | |||
248 | 229 | if (job->is_task) | ||
249 | 230 | { | ||
250 | 231 | if (strcmp (instance->state, "waiting") == 0) | ||
251 | 232 | update_status (state, job, instance, NULL, true); | ||
252 | 233 | } | ||
253 | 234 | else | ||
254 | 235 | { | ||
255 | 236 | if (strcmp (instance->goal, "start") == 0) | ||
256 | 237 | { | ||
257 | 238 | if (strcmp (instance->state, "running") == 0) | ||
258 | 239 | update_status (state, job, instance, "Starting", true); | ||
259 | 240 | } | ||
260 | 241 | else if (strcmp (instance->goal, "stop") == 0) | ||
261 | 242 | { | ||
262 | 243 | if (strcmp (instance->state, "waiting") == 0) | ||
263 | 244 | update_status (state, job, instance, "Stopping", true); | ||
264 | 245 | } | ||
265 | 246 | } | ||
266 | 247 | } | ||
267 | 248 | |||
268 | 249 | static void | ||
269 | 250 | on_disconnect (state_t *state) | ||
270 | 251 | { | ||
271 | 252 | ply_trace ("disconnected from boot status daemon"); | ||
272 | 253 | ply_event_loop_exit (state->loop, 0); | ||
273 | 254 | } | ||
274 | 255 | |||
275 | 256 | int | ||
276 | 257 | main (int argc, | ||
277 | 258 | char **argv) | ||
278 | 259 | { | ||
279 | 260 | state_t state = { 0 }; | ||
280 | 261 | bool should_help, should_be_verbose; | ||
281 | 262 | bool is_connected; | ||
282 | 263 | int exit_code; | ||
283 | 264 | |||
284 | 265 | exit_code = 0; | ||
285 | 266 | |||
286 | 267 | signal (SIGPIPE, SIG_IGN); | ||
287 | 268 | |||
288 | 269 | state.loop = ply_event_loop_new (); | ||
289 | 270 | state.client = ply_boot_client_new (); | ||
290 | 271 | state.command_parser = ply_command_parser_new ("plymouth-upstart-bridge", "Upstart job state bridge"); | ||
291 | 272 | |||
292 | 273 | ply_command_parser_add_options (state.command_parser, | ||
293 | 274 | "help", "This help message", PLY_COMMAND_OPTION_TYPE_FLAG, | ||
294 | 275 | "debug", "Enable verbose debug logging", PLY_COMMAND_OPTION_TYPE_FLAG, | ||
295 | 276 | NULL); | ||
296 | 277 | |||
297 | 278 | if (!ply_command_parser_parse_arguments (state.command_parser, state.loop, argv, argc)) | ||
298 | 279 | { | ||
299 | 280 | char *help_string; | ||
300 | 281 | |||
301 | 282 | help_string = ply_command_parser_get_help_string (state.command_parser); | ||
302 | 283 | |||
303 | 284 | ply_error ("%s", help_string); | ||
304 | 285 | |||
305 | 286 | free (help_string); | ||
306 | 287 | return 1; | ||
307 | 288 | } | ||
308 | 289 | |||
309 | 290 | ply_command_parser_get_options (state.command_parser, | ||
310 | 291 | "help", &should_help, | ||
311 | 292 | "debug", &should_be_verbose, | ||
312 | 293 | NULL); | ||
313 | 294 | |||
314 | 295 | if (should_help) | ||
315 | 296 | { | ||
316 | 297 | char *help_string; | ||
317 | 298 | |||
318 | 299 | help_string = ply_command_parser_get_help_string (state.command_parser); | ||
319 | 300 | |||
320 | 301 | puts (help_string); | ||
321 | 302 | |||
322 | 303 | free (help_string); | ||
323 | 304 | return 0; | ||
324 | 305 | } | ||
325 | 306 | |||
326 | 307 | if (should_be_verbose && !ply_is_tracing ()) | ||
327 | 308 | ply_toggle_tracing (); | ||
328 | 309 | |||
329 | 310 | setupterm (NULL, STDOUT_FILENO, NULL); | ||
330 | 311 | |||
331 | 312 | is_connected = ply_boot_client_connect (state.client, | ||
332 | 313 | (ply_boot_client_disconnect_handler_t) | ||
333 | 314 | on_disconnect, &state); | ||
334 | 315 | if (!is_connected) | ||
335 | 316 | { | ||
336 | 317 | ply_trace ("daemon not running"); | ||
337 | 318 | return 1; | ||
338 | 319 | } | ||
339 | 320 | |||
340 | 321 | ply_boot_client_attach_to_event_loop (state.client, state.loop); | ||
341 | 322 | state.upstart = ply_upstart_monitor_new (state.loop); | ||
342 | 323 | if (!state.upstart) | ||
343 | 324 | return 1; | ||
344 | 325 | ply_upstart_monitor_add_state_changed_handler (state.upstart, | ||
345 | 326 | (ply_upstart_monitor_state_changed_handler_t) | ||
346 | 327 | on_state_changed, &state); | ||
347 | 328 | ply_upstart_monitor_add_failed_handler (state.upstart, on_failed, &state); | ||
348 | 329 | |||
349 | 330 | exit_code = ply_event_loop_run (state.loop); | ||
350 | 331 | |||
351 | 332 | ply_upstart_monitor_free (state.upstart); | ||
352 | 333 | ply_boot_client_free (state.client); | ||
353 | 334 | |||
354 | 335 | ply_event_loop_free (state.loop); | ||
355 | 336 | |||
356 | 337 | return exit_code; | ||
357 | 338 | } | ||
358 | 339 | /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ | ||
359 | 0 | 340 | ||
360 | === added directory '.pc/no-print-empty-description.patch' | |||
361 | === added directory '.pc/no-print-empty-description.patch/src' | |||
362 | === added directory '.pc/no-print-empty-description.patch/src/upstart-bridge' | |||
363 | === added file '.pc/no-print-empty-description.patch/src/upstart-bridge/ply-upstart-monitor.c' | |||
364 | --- .pc/no-print-empty-description.patch/src/upstart-bridge/ply-upstart-monitor.c 1970-01-01 00:00:00 +0000 | |||
365 | +++ .pc/no-print-empty-description.patch/src/upstart-bridge/ply-upstart-monitor.c 2014-03-14 10:43:52 +0000 | |||
366 | @@ -0,0 +1,1182 @@ | |||
367 | 1 | /* ply-upstart-monitor.c - Upstart D-Bus monitor | ||
368 | 2 | * | ||
369 | 3 | * Copyright (C) 2010, 2011 Canonical Ltd. | ||
370 | 4 | * | ||
371 | 5 | * This program is free software; you can redistribute it and/or modify | ||
372 | 6 | * it under the terms of the GNU General Public License as published by | ||
373 | 7 | * the Free Software Foundation; either version 2, or (at your option) | ||
374 | 8 | * any later version. | ||
375 | 9 | * | ||
376 | 10 | * This program is distributed in the hope that it will be useful, | ||
377 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
378 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
379 | 13 | * GNU General Public License for more details. | ||
380 | 14 | * | ||
381 | 15 | * You should have received a copy of the GNU General Public License | ||
382 | 16 | * along with this program; if not, write to the Free Software | ||
383 | 17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
384 | 18 | * 02111-1307, USA. | ||
385 | 19 | * | ||
386 | 20 | * Written by: Colin Watson <cjwatson@ubuntu.com> | ||
387 | 21 | */ | ||
388 | 22 | #include "config.h" | ||
389 | 23 | #include "ply-upstart-monitor.h" | ||
390 | 24 | |||
391 | 25 | #include <assert.h> | ||
392 | 26 | #include <stdbool.h> | ||
393 | 27 | #include <stdlib.h> | ||
394 | 28 | #include <stdio.h> | ||
395 | 29 | #include <string.h> | ||
396 | 30 | #include <sys/eventfd.h> | ||
397 | 31 | |||
398 | 32 | #include <dbus/dbus.h> | ||
399 | 33 | |||
400 | 34 | #include "ply-logger.h" | ||
401 | 35 | #include "ply-event-loop.h" | ||
402 | 36 | #include "ply-hashtable.h" | ||
403 | 37 | #include "ply-list.h" | ||
404 | 38 | #include "ply-utils.h" | ||
405 | 39 | |||
406 | 40 | typedef struct | ||
407 | 41 | { | ||
408 | 42 | ply_upstart_monitor_t *monitor; | ||
409 | 43 | DBusTimeout *timeout; | ||
410 | 44 | } ply_upstart_monitor_timeout_t; | ||
411 | 45 | |||
412 | 46 | struct _ply_upstart_monitor | ||
413 | 47 | { | ||
414 | 48 | DBusConnection *connection; | ||
415 | 49 | ply_event_loop_t *loop; | ||
416 | 50 | ply_hashtable_t *jobs; | ||
417 | 51 | ply_hashtable_t *all_instances; | ||
418 | 52 | ply_upstart_monitor_state_changed_handler_t state_changed_handler; | ||
419 | 53 | void *state_changed_data; | ||
420 | 54 | ply_upstart_monitor_failed_handler_t failed_handler; | ||
421 | 55 | void *failed_data; | ||
422 | 56 | int dispatch_fd; | ||
423 | 57 | }; | ||
424 | 58 | |||
425 | 59 | typedef struct | ||
426 | 60 | { | ||
427 | 61 | ply_upstart_monitor_t *monitor; | ||
428 | 62 | ply_upstart_monitor_job_properties_t properties; | ||
429 | 63 | ply_hashtable_t *instances; | ||
430 | 64 | ply_list_t *pending_calls; | ||
431 | 65 | } ply_upstart_monitor_job_t; | ||
432 | 66 | |||
433 | 67 | typedef struct | ||
434 | 68 | { | ||
435 | 69 | ply_upstart_monitor_job_t *job; | ||
436 | 70 | ply_upstart_monitor_instance_properties_t properties; | ||
437 | 71 | ply_list_t *pending_calls; | ||
438 | 72 | uint32_t state_changed : 1; | ||
439 | 73 | uint32_t call_failed : 1; | ||
440 | 74 | } ply_upstart_monitor_instance_t; | ||
441 | 75 | |||
442 | 76 | #define UPSTART_SERVICE NULL | ||
443 | 77 | #define DBUS_ADDRESS_UPSTART "unix:abstract=/com/ubuntu/upstart" | ||
444 | 78 | #define UPSTART_PATH "/com/ubuntu/Upstart" | ||
445 | 79 | #define UPSTART_INTERFACE_0_6 "com.ubuntu.Upstart0_6" | ||
446 | 80 | #define UPSTART_INTERFACE_0_6_JOB "com.ubuntu.Upstart0_6.Job" | ||
447 | 81 | #define UPSTART_INTERFACE_0_6_INSTANCE "com.ubuntu.Upstart0_6.Instance" | ||
448 | 82 | |||
449 | 83 | /* Remove an entry from a hashtable, free the key, and return the data. */ | ||
450 | 84 | static void * | ||
451 | 85 | hashtable_remove_and_free_key (ply_hashtable_t *hashtable, | ||
452 | 86 | const void *key) | ||
453 | 87 | { | ||
454 | 88 | void *reply_key, *reply_data; | ||
455 | 89 | |||
456 | 90 | if (!ply_hashtable_lookup_full (hashtable, (void *) key, | ||
457 | 91 | &reply_key, &reply_data)) | ||
458 | 92 | return NULL; | ||
459 | 93 | ply_hashtable_remove (hashtable, (void *) key); | ||
460 | 94 | free (reply_key); | ||
461 | 95 | |||
462 | 96 | return reply_data; | ||
463 | 97 | } | ||
464 | 98 | |||
465 | 99 | /* We assume, in general, that Upstart responds to D-Bus messages in a | ||
466 | 100 | * single thread, and that it processes messages on a given connection in | ||
467 | 101 | * the order in which they were sent. Taken together, these assumptions | ||
468 | 102 | * imply a kind of coherence: a Properties.GetAll reply received after a | ||
469 | 103 | * StateChanged signal must have been computed entirely after the state | ||
470 | 104 | * change. Thus, if this function returns false (properties have not been | ||
471 | 105 | * fetched yet), it should be safe to record an event as call until such | ||
472 | 106 | * time as the properties of the instance are known. | ||
473 | 107 | */ | ||
474 | 108 | static bool | ||
475 | 109 | instance_is_initialized (ply_upstart_monitor_instance_t *instance) | ||
476 | 110 | { | ||
477 | 111 | /* Note that the job may not have a description. */ | ||
478 | 112 | if (instance->job->properties.name && | ||
479 | 113 | instance->properties.name && instance->properties.goal && | ||
480 | 114 | instance->properties.state) | ||
481 | 115 | return true; | ||
482 | 116 | else | ||
483 | 117 | return false; | ||
484 | 118 | } | ||
485 | 119 | |||
486 | 120 | static void | ||
487 | 121 | on_get_all_instance_properties_finished (DBusPendingCall *call, | ||
488 | 122 | ply_upstart_monitor_instance_t *instance) | ||
489 | 123 | { | ||
490 | 124 | DBusMessage *reply; | ||
491 | 125 | DBusMessageIter iter, array_iter, dict_iter, variant_iter; | ||
492 | 126 | const char *key, *name, *goal, *state; | ||
493 | 127 | ply_upstart_monitor_t *monitor; | ||
494 | 128 | |||
495 | 129 | assert (call != NULL); | ||
496 | 130 | assert (instance != NULL); | ||
497 | 131 | |||
498 | 132 | reply = dbus_pending_call_steal_reply (call); | ||
499 | 133 | if (reply == NULL) | ||
500 | 134 | return; | ||
501 | 135 | if (dbus_message_get_type (reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN) | ||
502 | 136 | goto out; | ||
503 | 137 | |||
504 | 138 | dbus_message_iter_init (reply, &iter); | ||
505 | 139 | if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) | ||
506 | 140 | goto out; | ||
507 | 141 | dbus_message_iter_recurse (&iter, &array_iter); | ||
508 | 142 | |||
509 | 143 | while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_DICT_ENTRY) | ||
510 | 144 | { | ||
511 | 145 | dbus_message_iter_recurse (&array_iter, &dict_iter); | ||
512 | 146 | |||
513 | 147 | if (dbus_message_iter_get_arg_type (&dict_iter) != DBUS_TYPE_STRING) | ||
514 | 148 | goto next_item; | ||
515 | 149 | |||
516 | 150 | dbus_message_iter_get_basic (&dict_iter, &key); | ||
517 | 151 | if (key == NULL) | ||
518 | 152 | goto next_item; | ||
519 | 153 | |||
520 | 154 | dbus_message_iter_next (&dict_iter); | ||
521 | 155 | if (dbus_message_iter_get_arg_type (&dict_iter) != DBUS_TYPE_VARIANT) | ||
522 | 156 | goto next_item; | ||
523 | 157 | dbus_message_iter_recurse (&dict_iter, &variant_iter); | ||
524 | 158 | if (dbus_message_iter_get_arg_type (&variant_iter) != DBUS_TYPE_STRING) | ||
525 | 159 | goto next_item; | ||
526 | 160 | |||
527 | 161 | if (strcmp (key, "name") == 0) | ||
528 | 162 | { | ||
529 | 163 | dbus_message_iter_get_basic (&variant_iter, &name); | ||
530 | 164 | if (name != NULL) | ||
531 | 165 | { | ||
532 | 166 | ply_trace ("%s: name = '%s'", | ||
533 | 167 | instance->job->properties.name, name); | ||
534 | 168 | instance->properties.name = strdup (name); | ||
535 | 169 | } | ||
536 | 170 | } | ||
537 | 171 | else if (strcmp (key, "goal") == 0) | ||
538 | 172 | { | ||
539 | 173 | dbus_message_iter_get_basic (&variant_iter, &goal); | ||
540 | 174 | if (goal != NULL) | ||
541 | 175 | { | ||
542 | 176 | ply_trace ("%s: goal = '%s'", | ||
543 | 177 | instance->job->properties.name, goal); | ||
544 | 178 | instance->properties.goal = strdup (goal); | ||
545 | 179 | } | ||
546 | 180 | } | ||
547 | 181 | else if (strcmp (key, "state") == 0) | ||
548 | 182 | { | ||
549 | 183 | dbus_message_iter_get_basic (&variant_iter, &state); | ||
550 | 184 | if (state != NULL) | ||
551 | 185 | { | ||
552 | 186 | ply_trace ("%s: state = '%s'", | ||
553 | 187 | instance->job->properties.name, state); | ||
554 | 188 | instance->properties.state = strdup (state); | ||
555 | 189 | } | ||
556 | 190 | } | ||
557 | 191 | |||
558 | 192 | next_item: | ||
559 | 193 | dbus_message_iter_next (&array_iter); | ||
560 | 194 | } | ||
561 | 195 | |||
562 | 196 | out: | ||
563 | 197 | dbus_message_unref (reply); | ||
564 | 198 | |||
565 | 199 | if (instance_is_initialized (instance)) | ||
566 | 200 | { | ||
567 | 201 | /* Process any call events. */ | ||
568 | 202 | monitor = instance->job->monitor; | ||
569 | 203 | |||
570 | 204 | if (instance->state_changed && monitor->state_changed_handler) | ||
571 | 205 | monitor->state_changed_handler (monitor->state_changed_data, NULL, | ||
572 | 206 | &instance->job->properties, | ||
573 | 207 | &instance->properties); | ||
574 | 208 | instance->state_changed = false; | ||
575 | 209 | |||
576 | 210 | if (instance->call_failed && monitor->failed_handler) | ||
577 | 211 | monitor->failed_handler (monitor->failed_data, | ||
578 | 212 | &instance->job->properties, | ||
579 | 213 | &instance->properties, | ||
580 | 214 | instance->properties.failed); | ||
581 | 215 | instance->call_failed = false; | ||
582 | 216 | } | ||
583 | 217 | } | ||
584 | 218 | |||
585 | 219 | static void | ||
586 | 220 | on_get_all_job_properties_finished (DBusPendingCall *call, | ||
587 | 221 | ply_upstart_monitor_job_t *job) | ||
588 | 222 | { | ||
589 | 223 | DBusMessage *reply; | ||
590 | 224 | DBusMessageIter iter, array_iter, dict_iter, variant_iter; | ||
591 | 225 | const char *key, *name, *description; | ||
592 | 226 | dbus_uint32_t task; | ||
593 | 227 | |||
594 | 228 | assert (call != NULL); | ||
595 | 229 | assert (job != NULL); | ||
596 | 230 | |||
597 | 231 | reply = dbus_pending_call_steal_reply (call); | ||
598 | 232 | if (reply == NULL) | ||
599 | 233 | return; | ||
600 | 234 | if (dbus_message_get_type (reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN) | ||
601 | 235 | goto out; | ||
602 | 236 | |||
603 | 237 | dbus_message_iter_init (reply, &iter); | ||
604 | 238 | if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) | ||
605 | 239 | goto out; | ||
606 | 240 | dbus_message_iter_recurse (&iter, &array_iter); | ||
607 | 241 | |||
608 | 242 | while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_DICT_ENTRY) | ||
609 | 243 | { | ||
610 | 244 | dbus_message_iter_recurse (&array_iter, &dict_iter); | ||
611 | 245 | |||
612 | 246 | if (dbus_message_iter_get_arg_type (&dict_iter) != DBUS_TYPE_STRING) | ||
613 | 247 | goto next_item; | ||
614 | 248 | |||
615 | 249 | dbus_message_iter_get_basic (&dict_iter, &key); | ||
616 | 250 | if (key == NULL) | ||
617 | 251 | goto next_item; | ||
618 | 252 | |||
619 | 253 | dbus_message_iter_next (&dict_iter); | ||
620 | 254 | if (dbus_message_iter_get_arg_type (&dict_iter) != DBUS_TYPE_VARIANT) | ||
621 | 255 | goto next_item; | ||
622 | 256 | dbus_message_iter_recurse (&dict_iter, &variant_iter); | ||
623 | 257 | |||
624 | 258 | if (strcmp (key, "name") == 0) | ||
625 | 259 | { | ||
626 | 260 | if (dbus_message_iter_get_arg_type (&variant_iter) != | ||
627 | 261 | DBUS_TYPE_STRING) | ||
628 | 262 | goto next_item; | ||
629 | 263 | dbus_message_iter_get_basic (&variant_iter, &name); | ||
630 | 264 | if (name != NULL) | ||
631 | 265 | { | ||
632 | 266 | ply_trace ("name = '%s'", name); | ||
633 | 267 | job->properties.name = strdup (name); | ||
634 | 268 | } | ||
635 | 269 | } | ||
636 | 270 | else if (strcmp (key, "description") == 0) | ||
637 | 271 | { | ||
638 | 272 | if (dbus_message_iter_get_arg_type (&variant_iter) != | ||
639 | 273 | DBUS_TYPE_STRING) | ||
640 | 274 | goto next_item; | ||
641 | 275 | dbus_message_iter_get_basic (&variant_iter, &description); | ||
642 | 276 | if (description != NULL) | ||
643 | 277 | { | ||
644 | 278 | ply_trace ("description = '%s'", description); | ||
645 | 279 | job->properties.description = strdup (description); | ||
646 | 280 | } | ||
647 | 281 | } | ||
648 | 282 | else if (strcmp (key, "task") == 0) | ||
649 | 283 | { | ||
650 | 284 | if (dbus_message_iter_get_arg_type (&variant_iter) != | ||
651 | 285 | DBUS_TYPE_BOOLEAN) | ||
652 | 286 | goto next_item; | ||
653 | 287 | dbus_message_iter_get_basic (&variant_iter, &task); | ||
654 | 288 | ply_trace ("task = %s", task ? "TRUE" : "FALSE"); | ||
655 | 289 | job->properties.is_task = task ? true : false; | ||
656 | 290 | } | ||
657 | 291 | |||
658 | 292 | next_item: | ||
659 | 293 | dbus_message_iter_next (&array_iter); | ||
660 | 294 | } | ||
661 | 295 | |||
662 | 296 | out: | ||
663 | 297 | dbus_message_unref (reply); | ||
664 | 298 | } | ||
665 | 299 | |||
666 | 300 | static void | ||
667 | 301 | remove_instance_internal (ply_upstart_monitor_job_t *job, const char *path) | ||
668 | 302 | { | ||
669 | 303 | ply_upstart_monitor_instance_t *instance; | ||
670 | 304 | ply_list_node_t *node; | ||
671 | 305 | |||
672 | 306 | instance = hashtable_remove_and_free_key (job->instances, path); | ||
673 | 307 | if (instance == NULL) | ||
674 | 308 | return; | ||
675 | 309 | hashtable_remove_and_free_key (job->monitor->all_instances, path); | ||
676 | 310 | |||
677 | 311 | node = ply_list_get_first_node (instance->pending_calls); | ||
678 | 312 | while (node != NULL) | ||
679 | 313 | { | ||
680 | 314 | DBusPendingCall *call; | ||
681 | 315 | ply_list_node_t *next_node; | ||
682 | 316 | |||
683 | 317 | call = ply_list_node_get_data (node); | ||
684 | 318 | next_node = ply_list_get_next_node (instance->pending_calls, node); | ||
685 | 319 | dbus_pending_call_cancel (call); | ||
686 | 320 | dbus_pending_call_unref (call); | ||
687 | 321 | node = next_node; | ||
688 | 322 | } | ||
689 | 323 | ply_list_free (instance->pending_calls); | ||
690 | 324 | |||
691 | 325 | free (instance->properties.name); | ||
692 | 326 | free (instance->properties.goal); | ||
693 | 327 | free (instance->properties.state); | ||
694 | 328 | free (instance); | ||
695 | 329 | } | ||
696 | 330 | |||
697 | 331 | static void | ||
698 | 332 | add_instance (ply_upstart_monitor_job_t *job, | ||
699 | 333 | const char *path) | ||
700 | 334 | { | ||
701 | 335 | ply_upstart_monitor_instance_t *instance; | ||
702 | 336 | DBusMessage *message; | ||
703 | 337 | const char *interface = UPSTART_INTERFACE_0_6_INSTANCE; | ||
704 | 338 | DBusPendingCall *call; | ||
705 | 339 | |||
706 | 340 | ply_trace ("adding instance: %s", path); | ||
707 | 341 | |||
708 | 342 | remove_instance_internal (job, path); | ||
709 | 343 | |||
710 | 344 | instance = calloc (1, sizeof (ply_upstart_monitor_instance_t)); | ||
711 | 345 | instance->job = job; | ||
712 | 346 | instance->properties.name = NULL; | ||
713 | 347 | instance->properties.goal = NULL; | ||
714 | 348 | instance->properties.state = NULL; | ||
715 | 349 | instance->properties.failed = false; | ||
716 | 350 | instance->pending_calls = ply_list_new (); | ||
717 | 351 | instance->state_changed = false; | ||
718 | 352 | instance->call_failed = false; | ||
719 | 353 | |||
720 | 354 | /* Keep a hash of instances per job, to make InstanceRemoved handling | ||
721 | 355 | * easy. | ||
722 | 356 | */ | ||
723 | 357 | ply_hashtable_insert (job->instances, strdup (path), instance); | ||
724 | 358 | /* Keep a separate hash of all instances, to make StateChanged handling | ||
725 | 359 | * easy. | ||
726 | 360 | */ | ||
727 | 361 | ply_hashtable_insert (job->monitor->all_instances, strdup (path), instance); | ||
728 | 362 | |||
729 | 363 | /* Ask Upstart for the name, goal, and state properties. */ | ||
730 | 364 | ply_trace ("fetching properties of instance %s", path); | ||
731 | 365 | message = dbus_message_new_method_call (UPSTART_SERVICE, path, | ||
732 | 366 | DBUS_INTERFACE_PROPERTIES, "GetAll"); | ||
733 | 367 | dbus_message_append_args (message, | ||
734 | 368 | DBUS_TYPE_STRING, &interface, | ||
735 | 369 | DBUS_TYPE_INVALID); | ||
736 | 370 | dbus_connection_send_with_reply (job->monitor->connection, message, | ||
737 | 371 | &call, -1); | ||
738 | 372 | dbus_message_unref (message); | ||
739 | 373 | if (call != NULL) | ||
740 | 374 | { | ||
741 | 375 | dbus_pending_call_set_notify (call, | ||
742 | 376 | (DBusPendingCallNotifyFunction) | ||
743 | 377 | on_get_all_instance_properties_finished, | ||
744 | 378 | instance, NULL); | ||
745 | 379 | ply_list_append_data (instance->pending_calls, call); | ||
746 | 380 | } | ||
747 | 381 | } | ||
748 | 382 | |||
749 | 383 | static void | ||
750 | 384 | remove_instance (ply_upstart_monitor_job_t *job, | ||
751 | 385 | const char *path) | ||
752 | 386 | { | ||
753 | 387 | ply_trace ("removing instance: %s", path); | ||
754 | 388 | |||
755 | 389 | remove_instance_internal (job, path); | ||
756 | 390 | } | ||
757 | 391 | |||
758 | 392 | static void | ||
759 | 393 | on_get_all_instances_finished (DBusPendingCall *call, | ||
760 | 394 | ply_upstart_monitor_job_t *job) | ||
761 | 395 | { | ||
762 | 396 | DBusMessage *reply; | ||
763 | 397 | DBusError error; | ||
764 | 398 | char **instances; | ||
765 | 399 | int n_instances, i; | ||
766 | 400 | |||
767 | 401 | assert (call != NULL); | ||
768 | 402 | assert (job != NULL); | ||
769 | 403 | |||
770 | 404 | reply = dbus_pending_call_steal_reply (call); | ||
771 | 405 | if (reply == NULL) | ||
772 | 406 | return; | ||
773 | 407 | if (dbus_message_get_type (reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN) | ||
774 | 408 | goto out; | ||
775 | 409 | |||
776 | 410 | dbus_error_init (&error); | ||
777 | 411 | dbus_message_get_args (reply, &error, | ||
778 | 412 | DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, | ||
779 | 413 | &instances, &n_instances, | ||
780 | 414 | DBUS_TYPE_INVALID); | ||
781 | 415 | if (dbus_error_is_set (&error)) | ||
782 | 416 | goto out; | ||
783 | 417 | dbus_error_free (&error); | ||
784 | 418 | |||
785 | 419 | for (i = 0; i < n_instances; ++i) | ||
786 | 420 | add_instance (job, instances[i]); | ||
787 | 421 | |||
788 | 422 | dbus_free_string_array (instances); | ||
789 | 423 | |||
790 | 424 | out: | ||
791 | 425 | dbus_message_unref (reply); | ||
792 | 426 | } | ||
793 | 427 | |||
794 | 428 | static void | ||
795 | 429 | free_job_instance (void *key, void *data, void *user_data) | ||
796 | 430 | { | ||
797 | 431 | const char *path = key; | ||
798 | 432 | ply_upstart_monitor_instance_t *instance = data; | ||
799 | 433 | ply_upstart_monitor_t *monitor = user_data; | ||
800 | 434 | |||
801 | 435 | assert (monitor != NULL); | ||
802 | 436 | |||
803 | 437 | if (instance == NULL) | ||
804 | 438 | return; | ||
805 | 439 | |||
806 | 440 | hashtable_remove_and_free_key (monitor->all_instances, path); | ||
807 | 441 | free (instance->properties.name); | ||
808 | 442 | free (instance->properties.goal); | ||
809 | 443 | free (instance->properties.state); | ||
810 | 444 | free (instance); | ||
811 | 445 | } | ||
812 | 446 | |||
813 | 447 | static void | ||
814 | 448 | remove_job_internal (ply_upstart_monitor_t *monitor, const char *path) | ||
815 | 449 | { | ||
816 | 450 | ply_upstart_monitor_job_t *job; | ||
817 | 451 | ply_list_node_t *node; | ||
818 | 452 | |||
819 | 453 | job = hashtable_remove_and_free_key (monitor->jobs, path); | ||
820 | 454 | if (job == NULL) | ||
821 | 455 | return; | ||
822 | 456 | |||
823 | 457 | node = ply_list_get_first_node (job->pending_calls); | ||
824 | 458 | while (node != NULL) | ||
825 | 459 | { | ||
826 | 460 | DBusPendingCall *call; | ||
827 | 461 | ply_list_node_t *next_node; | ||
828 | 462 | |||
829 | 463 | call = ply_list_node_get_data (node); | ||
830 | 464 | next_node = ply_list_get_next_node (job->pending_calls, node); | ||
831 | 465 | dbus_pending_call_cancel (call); | ||
832 | 466 | dbus_pending_call_unref (call); | ||
833 | 467 | node = next_node; | ||
834 | 468 | } | ||
835 | 469 | ply_list_free (job->pending_calls); | ||
836 | 470 | |||
837 | 471 | free (job->properties.name); | ||
838 | 472 | free (job->properties.description); | ||
839 | 473 | ply_hashtable_foreach (job->instances, free_job_instance, monitor); | ||
840 | 474 | ply_hashtable_free (job->instances); | ||
841 | 475 | free (job); | ||
842 | 476 | } | ||
843 | 477 | |||
844 | 478 | static void | ||
845 | 479 | add_job (ply_upstart_monitor_t *monitor, const char *path) | ||
846 | 480 | { | ||
847 | 481 | ply_upstart_monitor_job_t *job; | ||
848 | 482 | DBusMessage *message; | ||
849 | 483 | const char *interface = UPSTART_INTERFACE_0_6_JOB; | ||
850 | 484 | DBusPendingCall *call; | ||
851 | 485 | |||
852 | 486 | ply_trace ("adding job: %s", path); | ||
853 | 487 | |||
854 | 488 | remove_job_internal (monitor, path); | ||
855 | 489 | |||
856 | 490 | job = calloc (1, sizeof (ply_upstart_monitor_job_t)); | ||
857 | 491 | job->monitor = monitor; | ||
858 | 492 | job->properties.name = NULL; | ||
859 | 493 | job->properties.description = NULL; | ||
860 | 494 | job->properties.is_task = false; | ||
861 | 495 | job->instances = ply_hashtable_new (ply_hashtable_string_hash, | ||
862 | 496 | ply_hashtable_string_compare); | ||
863 | 497 | job->pending_calls = ply_list_new (); | ||
864 | 498 | |||
865 | 499 | ply_hashtable_insert (monitor->jobs, strdup (path), job); | ||
866 | 500 | |||
867 | 501 | /* Ask Upstart for the name and description properties. */ | ||
868 | 502 | ply_trace ("fetching properties of job %s", path); | ||
869 | 503 | message = dbus_message_new_method_call (UPSTART_SERVICE, path, | ||
870 | 504 | DBUS_INTERFACE_PROPERTIES, "GetAll"); | ||
871 | 505 | dbus_message_append_args (message, | ||
872 | 506 | DBUS_TYPE_STRING, &interface, | ||
873 | 507 | DBUS_TYPE_INVALID); | ||
874 | 508 | dbus_connection_send_with_reply (monitor->connection, message, &call, -1); | ||
875 | 509 | dbus_message_unref (message); | ||
876 | 510 | if (call != NULL) | ||
877 | 511 | { | ||
878 | 512 | dbus_pending_call_set_notify (call, | ||
879 | 513 | (DBusPendingCallNotifyFunction) | ||
880 | 514 | on_get_all_job_properties_finished, | ||
881 | 515 | job, | ||
882 | 516 | NULL); | ||
883 | 517 | ply_list_append_data (job->pending_calls, call); | ||
884 | 518 | } | ||
885 | 519 | |||
886 | 520 | /* Ask Upstart for a list of all instances of this job. */ | ||
887 | 521 | ply_trace ("calling GetAllInstances on job %s", path); | ||
888 | 522 | message = dbus_message_new_method_call (UPSTART_SERVICE, path, | ||
889 | 523 | UPSTART_INTERFACE_0_6_JOB, | ||
890 | 524 | "GetAllInstances"); | ||
891 | 525 | dbus_connection_send_with_reply (monitor->connection, message, &call, -1); | ||
892 | 526 | dbus_message_unref (message); | ||
893 | 527 | if (call != NULL) | ||
894 | 528 | { | ||
895 | 529 | dbus_pending_call_set_notify (call, | ||
896 | 530 | (DBusPendingCallNotifyFunction) | ||
897 | 531 | on_get_all_instances_finished, | ||
898 | 532 | job, | ||
899 | 533 | NULL); | ||
900 | 534 | ply_list_append_data (job->pending_calls, call); | ||
901 | 535 | } | ||
902 | 536 | } | ||
903 | 537 | |||
904 | 538 | static void | ||
905 | 539 | remove_job (ply_upstart_monitor_t *monitor, const char *path) | ||
906 | 540 | { | ||
907 | 541 | ply_trace ("removing job: %s", path); | ||
908 | 542 | |||
909 | 543 | remove_job_internal (monitor, path); | ||
910 | 544 | } | ||
911 | 545 | |||
912 | 546 | static void | ||
913 | 547 | on_get_all_jobs_finished (DBusPendingCall *call, | ||
914 | 548 | ply_upstart_monitor_t *monitor) | ||
915 | 549 | { | ||
916 | 550 | DBusMessage *reply; | ||
917 | 551 | DBusError error; | ||
918 | 552 | char **jobs; | ||
919 | 553 | int n_jobs, i; | ||
920 | 554 | |||
921 | 555 | assert (call != NULL); | ||
922 | 556 | assert (monitor != NULL); | ||
923 | 557 | |||
924 | 558 | reply = dbus_pending_call_steal_reply (call); | ||
925 | 559 | if (reply == NULL) | ||
926 | 560 | return; | ||
927 | 561 | if (dbus_message_get_type (reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN) | ||
928 | 562 | goto out; | ||
929 | 563 | |||
930 | 564 | dbus_error_init (&error); | ||
931 | 565 | dbus_message_get_args (reply, &error, | ||
932 | 566 | DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, | ||
933 | 567 | &jobs, &n_jobs, | ||
934 | 568 | DBUS_TYPE_INVALID); | ||
935 | 569 | if (dbus_error_is_set (&error)) | ||
936 | 570 | goto out; | ||
937 | 571 | dbus_error_free (&error); | ||
938 | 572 | |||
939 | 573 | for (i = 0; i < n_jobs; ++i) | ||
940 | 574 | add_job (monitor, jobs[i]); | ||
941 | 575 | |||
942 | 576 | dbus_free_string_array (jobs); | ||
943 | 577 | |||
944 | 578 | out: | ||
945 | 579 | dbus_message_unref (reply); | ||
946 | 580 | } | ||
947 | 581 | |||
948 | 582 | |||
949 | 583 | static DBusHandlerResult | ||
950 | 584 | job_added_handler (DBusConnection *connection, | ||
951 | 585 | DBusMessage *message, | ||
952 | 586 | ply_upstart_monitor_t *monitor) | ||
953 | 587 | { | ||
954 | 588 | DBusError error; | ||
955 | 589 | const char *signal_path; | ||
956 | 590 | |||
957 | 591 | ply_trace ("got JobAdded"); | ||
958 | 592 | dbus_error_init (&error); | ||
959 | 593 | if (dbus_message_get_args (message, &error, | ||
960 | 594 | DBUS_TYPE_OBJECT_PATH, &signal_path, | ||
961 | 595 | DBUS_TYPE_INVALID)) | ||
962 | 596 | add_job (monitor, signal_path); | ||
963 | 597 | dbus_error_free (&error); | ||
964 | 598 | return DBUS_HANDLER_RESULT_HANDLED; | ||
965 | 599 | } | ||
966 | 600 | |||
967 | 601 | static DBusHandlerResult | ||
968 | 602 | job_removed_handler (DBusConnection *connection, | ||
969 | 603 | DBusMessage *message, | ||
970 | 604 | ply_upstart_monitor_t *monitor) | ||
971 | 605 | { | ||
972 | 606 | DBusError error; | ||
973 | 607 | const char *signal_path; | ||
974 | 608 | |||
975 | 609 | ply_trace ("got JobRemoved"); | ||
976 | 610 | dbus_error_init (&error); | ||
977 | 611 | if (dbus_message_get_args (message, &error, | ||
978 | 612 | DBUS_TYPE_OBJECT_PATH, &signal_path, | ||
979 | 613 | DBUS_TYPE_INVALID)) | ||
980 | 614 | remove_job (monitor, signal_path); | ||
981 | 615 | dbus_error_free (&error); | ||
982 | 616 | return DBUS_HANDLER_RESULT_HANDLED; | ||
983 | 617 | } | ||
984 | 618 | |||
985 | 619 | static DBusHandlerResult | ||
986 | 620 | instance_added_handler (DBusConnection *connection, DBusMessage *message, | ||
987 | 621 | ply_upstart_monitor_t *monitor, const char *path) | ||
988 | 622 | { | ||
989 | 623 | DBusError error; | ||
990 | 624 | const char *signal_path; | ||
991 | 625 | ply_upstart_monitor_job_t *job; | ||
992 | 626 | |||
993 | 627 | ply_trace ("got %s InstanceAdded", path); | ||
994 | 628 | job = ply_hashtable_lookup (monitor->jobs, (void *) path); | ||
995 | 629 | if (job != NULL) | ||
996 | 630 | { | ||
997 | 631 | dbus_error_init (&error); | ||
998 | 632 | if (dbus_message_get_args (message, &error, | ||
999 | 633 | DBUS_TYPE_OBJECT_PATH, &signal_path, | ||
1000 | 634 | DBUS_TYPE_INVALID)) | ||
1001 | 635 | add_instance (job, signal_path); | ||
1002 | 636 | dbus_error_free (&error); | ||
1003 | 637 | } | ||
1004 | 638 | return DBUS_HANDLER_RESULT_HANDLED; | ||
1005 | 639 | } | ||
1006 | 640 | |||
1007 | 641 | static DBusHandlerResult | ||
1008 | 642 | instance_removed_handler (DBusConnection *connection, DBusMessage *message, | ||
1009 | 643 | ply_upstart_monitor_t *monitor, const char *path) | ||
1010 | 644 | { | ||
1011 | 645 | DBusError error; | ||
1012 | 646 | const char *signal_path; | ||
1013 | 647 | ply_upstart_monitor_job_t *job; | ||
1014 | 648 | |||
1015 | 649 | ply_trace ("got %s InstanceRemoved", path); | ||
1016 | 650 | job = ply_hashtable_lookup (monitor->jobs, (void *) path); | ||
1017 | 651 | if (job != NULL) | ||
1018 | 652 | { | ||
1019 | 653 | dbus_error_init (&error); | ||
1020 | 654 | if (dbus_message_get_args (message, &error, | ||
1021 | 655 | DBUS_TYPE_OBJECT_PATH, &signal_path, | ||
1022 | 656 | DBUS_TYPE_INVALID)) | ||
1023 | 657 | remove_instance (job, signal_path); | ||
1024 | 658 | dbus_error_free (&error); | ||
1025 | 659 | } | ||
1026 | 660 | return DBUS_HANDLER_RESULT_HANDLED; | ||
1027 | 661 | } | ||
1028 | 662 | |||
1029 | 663 | static DBusHandlerResult | ||
1030 | 664 | goal_changed_handler (DBusConnection *connection, DBusMessage *message, | ||
1031 | 665 | ply_upstart_monitor_t *monitor, const char *path) | ||
1032 | 666 | { | ||
1033 | 667 | DBusError error; | ||
1034 | 668 | const char *goal; | ||
1035 | 669 | ply_upstart_monitor_instance_t *instance; | ||
1036 | 670 | char *old_goal; | ||
1037 | 671 | |||
1038 | 672 | ply_trace ("got %s GoalChanged", path); | ||
1039 | 673 | instance = ply_hashtable_lookup (monitor->all_instances, (void *) path); | ||
1040 | 674 | if (instance != NULL) | ||
1041 | 675 | { | ||
1042 | 676 | dbus_error_init (&error); | ||
1043 | 677 | if (dbus_message_get_args (message, &error, | ||
1044 | 678 | DBUS_TYPE_STRING, &goal, | ||
1045 | 679 | DBUS_TYPE_INVALID)) | ||
1046 | 680 | { | ||
1047 | 681 | old_goal = instance->properties.goal; | ||
1048 | 682 | instance->properties.goal = strdup (goal); | ||
1049 | 683 | ply_trace ("goal changed from '%s' to '%s'", old_goal, goal); | ||
1050 | 684 | free (old_goal); | ||
1051 | 685 | } | ||
1052 | 686 | dbus_error_free (&error); | ||
1053 | 687 | } | ||
1054 | 688 | return DBUS_HANDLER_RESULT_HANDLED; | ||
1055 | 689 | } | ||
1056 | 690 | |||
1057 | 691 | static DBusHandlerResult | ||
1058 | 692 | state_changed_handler (DBusConnection *connection, DBusMessage *message, | ||
1059 | 693 | ply_upstart_monitor_t *monitor, const char *path) | ||
1060 | 694 | { | ||
1061 | 695 | DBusError error; | ||
1062 | 696 | const char *state; | ||
1063 | 697 | ply_upstart_monitor_instance_t *instance; | ||
1064 | 698 | char *old_state; | ||
1065 | 699 | |||
1066 | 700 | ply_trace ("got %s StateChanged", path); | ||
1067 | 701 | instance = ply_hashtable_lookup (monitor->all_instances, (void *) path); | ||
1068 | 702 | if (instance != NULL) | ||
1069 | 703 | { | ||
1070 | 704 | dbus_error_init (&error); | ||
1071 | 705 | if (dbus_message_get_args (message, &error, | ||
1072 | 706 | DBUS_TYPE_STRING, &state, | ||
1073 | 707 | DBUS_TYPE_INVALID)) | ||
1074 | 708 | { | ||
1075 | 709 | old_state = instance->properties.state; | ||
1076 | 710 | instance->properties.state = strdup (state); | ||
1077 | 711 | ply_trace ("state changed from '%s' to '%s'", old_state, state); | ||
1078 | 712 | if (strcmp (state, "starting") == 0) | ||
1079 | 713 | { | ||
1080 | 714 | /* Clear any old failed information. */ | ||
1081 | 715 | instance->properties.failed = 0; | ||
1082 | 716 | instance->call_failed = false; | ||
1083 | 717 | } | ||
1084 | 718 | if (instance_is_initialized (instance)) | ||
1085 | 719 | { | ||
1086 | 720 | if (monitor->state_changed_handler) | ||
1087 | 721 | monitor->state_changed_handler (monitor->state_changed_data, | ||
1088 | 722 | old_state, | ||
1089 | 723 | &instance->job->properties, | ||
1090 | 724 | &instance->properties); | ||
1091 | 725 | } | ||
1092 | 726 | else | ||
1093 | 727 | instance->state_changed = true; | ||
1094 | 728 | free (old_state); | ||
1095 | 729 | } | ||
1096 | 730 | dbus_error_free (&error); | ||
1097 | 731 | } | ||
1098 | 732 | return DBUS_HANDLER_RESULT_HANDLED; | ||
1099 | 733 | } | ||
1100 | 734 | |||
1101 | 735 | static DBusHandlerResult | ||
1102 | 736 | failed_handler (DBusConnection *connection, DBusMessage *message, | ||
1103 | 737 | ply_upstart_monitor_t *monitor, const char *path) | ||
1104 | 738 | { | ||
1105 | 739 | DBusError error; | ||
1106 | 740 | ply_upstart_monitor_instance_t *instance; | ||
1107 | 741 | dbus_int32_t failed_status; | ||
1108 | 742 | |||
1109 | 743 | ply_trace ("got %s Failed", path); | ||
1110 | 744 | instance = ply_hashtable_lookup (monitor->all_instances, (void *) path); | ||
1111 | 745 | if (instance != NULL) | ||
1112 | 746 | { | ||
1113 | 747 | dbus_error_init (&error); | ||
1114 | 748 | if (dbus_message_get_args (message, &error, | ||
1115 | 749 | DBUS_TYPE_INT32, &failed_status, | ||
1116 | 750 | DBUS_TYPE_INVALID)) | ||
1117 | 751 | { | ||
1118 | 752 | instance->properties.failed = failed_status; | ||
1119 | 753 | if (instance_is_initialized (instance)) | ||
1120 | 754 | { | ||
1121 | 755 | if (monitor->failed_handler) | ||
1122 | 756 | monitor->failed_handler (monitor->failed_data, | ||
1123 | 757 | &instance->job->properties, | ||
1124 | 758 | &instance->properties, | ||
1125 | 759 | (int) failed_status); | ||
1126 | 760 | } | ||
1127 | 761 | else | ||
1128 | 762 | instance->call_failed = true; | ||
1129 | 763 | } | ||
1130 | 764 | dbus_error_free (&error); | ||
1131 | 765 | } | ||
1132 | 766 | return DBUS_HANDLER_RESULT_HANDLED; | ||
1133 | 767 | } | ||
1134 | 768 | |||
1135 | 769 | static DBusHandlerResult | ||
1136 | 770 | message_handler (DBusConnection *connection, DBusMessage *message, void *data) | ||
1137 | 771 | { | ||
1138 | 772 | ply_upstart_monitor_t *monitor = data; | ||
1139 | 773 | const char *path; | ||
1140 | 774 | |||
1141 | 775 | assert (connection != NULL); | ||
1142 | 776 | assert (message != NULL); | ||
1143 | 777 | assert (monitor != NULL); | ||
1144 | 778 | |||
1145 | 779 | path = dbus_message_get_path (message); | ||
1146 | 780 | if (path == NULL) | ||
1147 | 781 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
1148 | 782 | |||
1149 | 783 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6, | ||
1150 | 784 | "JobAdded")) | ||
1151 | 785 | return job_added_handler (connection, message, monitor); | ||
1152 | 786 | |||
1153 | 787 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6, | ||
1154 | 788 | "JobRemoved")) | ||
1155 | 789 | return job_removed_handler (connection, message, monitor); | ||
1156 | 790 | |||
1157 | 791 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6_JOB, | ||
1158 | 792 | "InstanceAdded")) | ||
1159 | 793 | return instance_added_handler (connection, message, monitor, path); | ||
1160 | 794 | |||
1161 | 795 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6_JOB, | ||
1162 | 796 | "InstanceRemoved")) | ||
1163 | 797 | return instance_removed_handler (connection, message, monitor, path); | ||
1164 | 798 | |||
1165 | 799 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6_INSTANCE, | ||
1166 | 800 | "GoalChanged")) | ||
1167 | 801 | return goal_changed_handler (connection, message, monitor, path); | ||
1168 | 802 | |||
1169 | 803 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6_INSTANCE, | ||
1170 | 804 | "StateChanged")) | ||
1171 | 805 | return state_changed_handler (connection, message, monitor, path); | ||
1172 | 806 | |||
1173 | 807 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6_INSTANCE, | ||
1174 | 808 | "Failed")) | ||
1175 | 809 | return failed_handler (connection, message, monitor, path); | ||
1176 | 810 | |||
1177 | 811 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
1178 | 812 | } | ||
1179 | 813 | |||
1180 | 814 | ply_upstart_monitor_t * | ||
1181 | 815 | ply_upstart_monitor_new (ply_event_loop_t *loop) | ||
1182 | 816 | { | ||
1183 | 817 | DBusError error; | ||
1184 | 818 | DBusConnection *connection; | ||
1185 | 819 | ply_upstart_monitor_t *monitor; | ||
1186 | 820 | DBusMessage *message; | ||
1187 | 821 | DBusPendingCall *call; | ||
1188 | 822 | |||
1189 | 823 | dbus_error_init (&error); | ||
1190 | 824 | |||
1191 | 825 | /* Get a connection to the system bus and set it up to listen for messages | ||
1192 | 826 | * from Upstart. | ||
1193 | 827 | */ | ||
1194 | 828 | connection = dbus_connection_open (DBUS_ADDRESS_UPSTART, &error); | ||
1195 | 829 | if (connection == NULL) | ||
1196 | 830 | { | ||
1197 | 831 | ply_error ("unable to connect to system bus: %s", error.message); | ||
1198 | 832 | dbus_error_free (&error); | ||
1199 | 833 | return NULL; | ||
1200 | 834 | } | ||
1201 | 835 | dbus_error_free (&error); | ||
1202 | 836 | |||
1203 | 837 | monitor = calloc (1, sizeof (ply_upstart_monitor_t)); | ||
1204 | 838 | monitor->connection = connection; | ||
1205 | 839 | monitor->loop = NULL; | ||
1206 | 840 | monitor->jobs = ply_hashtable_new (ply_hashtable_string_hash, | ||
1207 | 841 | ply_hashtable_string_compare); | ||
1208 | 842 | monitor->all_instances = ply_hashtable_new (ply_hashtable_string_hash, | ||
1209 | 843 | ply_hashtable_string_compare); | ||
1210 | 844 | monitor->state_changed_handler = NULL; | ||
1211 | 845 | monitor->state_changed_data = NULL; | ||
1212 | 846 | monitor->failed_handler = NULL; | ||
1213 | 847 | monitor->failed_data = NULL; | ||
1214 | 848 | monitor->dispatch_fd = -1; | ||
1215 | 849 | |||
1216 | 850 | if (!dbus_connection_add_filter (connection, message_handler, monitor, NULL)) | ||
1217 | 851 | { | ||
1218 | 852 | ply_error ("unable to add filter to system bus connection"); | ||
1219 | 853 | ply_upstart_monitor_free (monitor); | ||
1220 | 854 | return NULL; | ||
1221 | 855 | } | ||
1222 | 856 | |||
1223 | 857 | ply_trace ("calling GetAllJobs"); | ||
1224 | 858 | message = dbus_message_new_method_call (UPSTART_SERVICE, UPSTART_PATH, | ||
1225 | 859 | UPSTART_INTERFACE_0_6, | ||
1226 | 860 | "GetAllJobs"); | ||
1227 | 861 | dbus_connection_send_with_reply (monitor->connection, message, &call, -1); | ||
1228 | 862 | dbus_message_unref (message); | ||
1229 | 863 | if (call != NULL) | ||
1230 | 864 | dbus_pending_call_set_notify (call, | ||
1231 | 865 | (DBusPendingCallNotifyFunction) | ||
1232 | 866 | on_get_all_jobs_finished, | ||
1233 | 867 | monitor, NULL); | ||
1234 | 868 | |||
1235 | 869 | if (loop != NULL) | ||
1236 | 870 | ply_upstart_monitor_connect_to_event_loop (monitor, loop); | ||
1237 | 871 | |||
1238 | 872 | return monitor; | ||
1239 | 873 | } | ||
1240 | 874 | |||
1241 | 875 | void | ||
1242 | 876 | ply_upstart_monitor_free (ply_upstart_monitor_t *monitor) | ||
1243 | 877 | { | ||
1244 | 878 | if (monitor == NULL) | ||
1245 | 879 | return; | ||
1246 | 880 | |||
1247 | 881 | ply_hashtable_free (monitor->all_instances); | ||
1248 | 882 | ply_hashtable_free (monitor->jobs); | ||
1249 | 883 | dbus_connection_unref (monitor->connection); | ||
1250 | 884 | if (monitor->dispatch_fd >= 0) | ||
1251 | 885 | close (monitor->dispatch_fd); | ||
1252 | 886 | free (monitor); | ||
1253 | 887 | } | ||
1254 | 888 | |||
1255 | 889 | static void | ||
1256 | 890 | read_watch_handler (void *data, int fd) | ||
1257 | 891 | { | ||
1258 | 892 | DBusWatch *watch = data; | ||
1259 | 893 | |||
1260 | 894 | assert (watch != NULL); | ||
1261 | 895 | |||
1262 | 896 | dbus_watch_handle (watch, DBUS_WATCH_READABLE); | ||
1263 | 897 | } | ||
1264 | 898 | |||
1265 | 899 | static void | ||
1266 | 900 | write_watch_handler (void *data, int fd) | ||
1267 | 901 | { | ||
1268 | 902 | DBusWatch *watch = data; | ||
1269 | 903 | |||
1270 | 904 | assert (watch != NULL); | ||
1271 | 905 | |||
1272 | 906 | dbus_watch_handle (watch, DBUS_WATCH_WRITABLE); | ||
1273 | 907 | } | ||
1274 | 908 | |||
1275 | 909 | static dbus_bool_t | ||
1276 | 910 | add_watch (DBusWatch *watch, void *data) | ||
1277 | 911 | { | ||
1278 | 912 | ply_upstart_monitor_t *monitor = data; | ||
1279 | 913 | unsigned int flags; | ||
1280 | 914 | int fd; | ||
1281 | 915 | ply_event_loop_fd_status_t status; | ||
1282 | 916 | ply_fd_watch_t *read_watch_event = NULL, *write_watch_event = NULL; | ||
1283 | 917 | |||
1284 | 918 | assert (monitor != NULL); | ||
1285 | 919 | assert (watch != NULL); | ||
1286 | 920 | |||
1287 | 921 | if (!dbus_watch_get_enabled (watch)) | ||
1288 | 922 | return TRUE; | ||
1289 | 923 | |||
1290 | 924 | assert (dbus_watch_get_data (watch) == NULL); | ||
1291 | 925 | |||
1292 | 926 | flags = dbus_watch_get_flags (watch); | ||
1293 | 927 | fd = dbus_watch_get_unix_fd (watch); | ||
1294 | 928 | |||
1295 | 929 | if (flags & DBUS_WATCH_READABLE) | ||
1296 | 930 | { | ||
1297 | 931 | status = PLY_EVENT_LOOP_FD_STATUS_HAS_DATA; | ||
1298 | 932 | read_watch_event = ply_event_loop_watch_fd (monitor->loop, fd, status, | ||
1299 | 933 | read_watch_handler, NULL, | ||
1300 | 934 | watch); | ||
1301 | 935 | if (read_watch_event == NULL) | ||
1302 | 936 | return FALSE; | ||
1303 | 937 | dbus_watch_set_data (watch, read_watch_event, NULL); | ||
1304 | 938 | } | ||
1305 | 939 | |||
1306 | 940 | if (flags & DBUS_WATCH_WRITABLE) | ||
1307 | 941 | { | ||
1308 | 942 | status = PLY_EVENT_LOOP_FD_STATUS_CAN_TAKE_DATA; | ||
1309 | 943 | write_watch_event = ply_event_loop_watch_fd (monitor->loop, fd, status, | ||
1310 | 944 | write_watch_handler, NULL, | ||
1311 | 945 | watch); | ||
1312 | 946 | if (write_watch_event == NULL) | ||
1313 | 947 | { | ||
1314 | 948 | if (read_watch_event != NULL) | ||
1315 | 949 | ply_event_loop_stop_watching_fd (monitor->loop, read_watch_event); | ||
1316 | 950 | return FALSE; | ||
1317 | 951 | } | ||
1318 | 952 | dbus_watch_set_data (watch, write_watch_event, NULL); | ||
1319 | 953 | } | ||
1320 | 954 | |||
1321 | 955 | return TRUE; | ||
1322 | 956 | } | ||
1323 | 957 | |||
1324 | 958 | static void | ||
1325 | 959 | remove_watch (DBusWatch *watch, void *data) | ||
1326 | 960 | { | ||
1327 | 961 | ply_upstart_monitor_t *monitor = data; | ||
1328 | 962 | ply_fd_watch_t *watch_event; | ||
1329 | 963 | |||
1330 | 964 | assert (monitor != NULL); | ||
1331 | 965 | assert (watch != NULL); | ||
1332 | 966 | |||
1333 | 967 | watch_event = dbus_watch_get_data (watch); | ||
1334 | 968 | if (watch_event == NULL) | ||
1335 | 969 | return; | ||
1336 | 970 | |||
1337 | 971 | ply_event_loop_stop_watching_fd (monitor->loop, watch_event); | ||
1338 | 972 | |||
1339 | 973 | dbus_watch_set_data (watch, NULL, NULL); | ||
1340 | 974 | } | ||
1341 | 975 | |||
1342 | 976 | static void | ||
1343 | 977 | toggled_watch (DBusWatch *watch, void *data) | ||
1344 | 978 | { | ||
1345 | 979 | if (dbus_watch_get_enabled (watch)) | ||
1346 | 980 | add_watch (watch, data); | ||
1347 | 981 | else | ||
1348 | 982 | remove_watch (watch, data); | ||
1349 | 983 | } | ||
1350 | 984 | |||
1351 | 985 | static ply_upstart_monitor_timeout_t * | ||
1352 | 986 | timeout_user_data_new (ply_upstart_monitor_t *monitor, DBusTimeout *timeout) | ||
1353 | 987 | { | ||
1354 | 988 | ply_upstart_monitor_timeout_t *monitor_timeout; | ||
1355 | 989 | |||
1356 | 990 | monitor_timeout = calloc (1, sizeof (ply_upstart_monitor_timeout_t)); | ||
1357 | 991 | monitor_timeout->monitor = monitor; | ||
1358 | 992 | monitor_timeout->timeout = timeout; | ||
1359 | 993 | |||
1360 | 994 | return monitor_timeout; | ||
1361 | 995 | } | ||
1362 | 996 | |||
1363 | 997 | static void | ||
1364 | 998 | timeout_user_data_free (void *data) | ||
1365 | 999 | { | ||
1366 | 1000 | ply_upstart_monitor_timeout_t *monitor_timeout = data; | ||
1367 | 1001 | |||
1368 | 1002 | free (monitor_timeout); | ||
1369 | 1003 | } | ||
1370 | 1004 | |||
1371 | 1005 | static void | ||
1372 | 1006 | timeout_handler (void *data, ply_event_loop_t *loop) | ||
1373 | 1007 | { | ||
1374 | 1008 | ply_upstart_monitor_timeout_t *monitor_timeout = data; | ||
1375 | 1009 | |||
1376 | 1010 | assert (monitor_timeout != NULL); | ||
1377 | 1011 | |||
1378 | 1012 | dbus_timeout_handle (monitor_timeout->timeout); | ||
1379 | 1013 | } | ||
1380 | 1014 | |||
1381 | 1015 | static dbus_bool_t | ||
1382 | 1016 | add_timeout (DBusTimeout *timeout, void *data) | ||
1383 | 1017 | { | ||
1384 | 1018 | ply_upstart_monitor_t *monitor = data; | ||
1385 | 1019 | int interval; | ||
1386 | 1020 | ply_upstart_monitor_timeout_t *monitor_timeout; | ||
1387 | 1021 | |||
1388 | 1022 | assert (monitor != NULL); | ||
1389 | 1023 | assert (timeout != NULL); | ||
1390 | 1024 | |||
1391 | 1025 | if (!dbus_timeout_get_enabled (timeout)) | ||
1392 | 1026 | return TRUE; | ||
1393 | 1027 | |||
1394 | 1028 | interval = dbus_timeout_get_interval (timeout) * 1000; | ||
1395 | 1029 | |||
1396 | 1030 | monitor_timeout = timeout_user_data_new (monitor, timeout); | ||
1397 | 1031 | |||
1398 | 1032 | ply_event_loop_watch_for_timeout (monitor->loop, (double) interval, | ||
1399 | 1033 | timeout_handler, monitor_timeout); | ||
1400 | 1034 | |||
1401 | 1035 | dbus_timeout_set_data (timeout, monitor_timeout, timeout_user_data_free); | ||
1402 | 1036 | |||
1403 | 1037 | return TRUE; | ||
1404 | 1038 | } | ||
1405 | 1039 | |||
1406 | 1040 | static void | ||
1407 | 1041 | remove_timeout (DBusTimeout *timeout, void *data) | ||
1408 | 1042 | { | ||
1409 | 1043 | ply_upstart_monitor_t *monitor = data; | ||
1410 | 1044 | ply_upstart_monitor_timeout_t *monitor_timeout; | ||
1411 | 1045 | |||
1412 | 1046 | assert (monitor != NULL); | ||
1413 | 1047 | assert (timeout != NULL); | ||
1414 | 1048 | |||
1415 | 1049 | monitor_timeout = dbus_timeout_get_data (timeout); | ||
1416 | 1050 | if (monitor_timeout == NULL) | ||
1417 | 1051 | return; | ||
1418 | 1052 | |||
1419 | 1053 | ply_event_loop_stop_watching_for_timeout (monitor->loop, | ||
1420 | 1054 | timeout_handler, monitor_timeout); | ||
1421 | 1055 | |||
1422 | 1056 | dbus_timeout_set_data (timeout, NULL, NULL); | ||
1423 | 1057 | } | ||
1424 | 1058 | |||
1425 | 1059 | static void | ||
1426 | 1060 | toggled_timeout (DBusTimeout *timeout, void *data) | ||
1427 | 1061 | { | ||
1428 | 1062 | if (dbus_timeout_get_enabled (timeout)) | ||
1429 | 1063 | add_timeout (timeout, data); | ||
1430 | 1064 | else | ||
1431 | 1065 | remove_timeout (timeout, data); | ||
1432 | 1066 | } | ||
1433 | 1067 | |||
1434 | 1068 | static void | ||
1435 | 1069 | dispatch_status (DBusConnection *connection, DBusDispatchStatus new_status, | ||
1436 | 1070 | void *data) | ||
1437 | 1071 | { | ||
1438 | 1072 | ply_upstart_monitor_t *monitor = data; | ||
1439 | 1073 | uint64_t event_payload; | ||
1440 | 1074 | |||
1441 | 1075 | assert (monitor != NULL); | ||
1442 | 1076 | |||
1443 | 1077 | if (new_status != DBUS_DISPATCH_DATA_REMAINS) | ||
1444 | 1078 | return; | ||
1445 | 1079 | |||
1446 | 1080 | /* wake up event loop */ | ||
1447 | 1081 | event_payload = 1; | ||
1448 | 1082 | ply_write (monitor->dispatch_fd, &event_payload, sizeof (event_payload)); | ||
1449 | 1083 | } | ||
1450 | 1084 | |||
1451 | 1085 | static void | ||
1452 | 1086 | dispatch (void *data, int fd) | ||
1453 | 1087 | { | ||
1454 | 1088 | ply_upstart_monitor_t *monitor = data; | ||
1455 | 1089 | uint64_t event_payload; | ||
1456 | 1090 | |||
1457 | 1091 | assert (monitor != NULL); | ||
1458 | 1092 | |||
1459 | 1093 | /* reset eventfd to zero */ | ||
1460 | 1094 | ply_read (fd, &event_payload, sizeof (event_payload)); | ||
1461 | 1095 | |||
1462 | 1096 | while (dbus_connection_dispatch (monitor->connection) == | ||
1463 | 1097 | DBUS_DISPATCH_DATA_REMAINS) | ||
1464 | 1098 | ; | ||
1465 | 1099 | } | ||
1466 | 1100 | |||
1467 | 1101 | bool | ||
1468 | 1102 | ply_upstart_monitor_connect_to_event_loop (ply_upstart_monitor_t *monitor, | ||
1469 | 1103 | ply_event_loop_t *loop) | ||
1470 | 1104 | { | ||
1471 | 1105 | ply_fd_watch_t *dispatch_event = NULL; | ||
1472 | 1106 | uint64_t event_payload; | ||
1473 | 1107 | |||
1474 | 1108 | assert (monitor != NULL); | ||
1475 | 1109 | |||
1476 | 1110 | monitor->loop = loop; | ||
1477 | 1111 | monitor->dispatch_fd = -1; | ||
1478 | 1112 | |||
1479 | 1113 | if (!dbus_connection_set_watch_functions (monitor->connection, | ||
1480 | 1114 | add_watch, | ||
1481 | 1115 | remove_watch, | ||
1482 | 1116 | toggled_watch, | ||
1483 | 1117 | monitor, NULL)) | ||
1484 | 1118 | goto err; | ||
1485 | 1119 | |||
1486 | 1120 | if (!dbus_connection_set_timeout_functions (monitor->connection, | ||
1487 | 1121 | add_timeout, | ||
1488 | 1122 | remove_timeout, | ||
1489 | 1123 | toggled_timeout, | ||
1490 | 1124 | monitor, NULL)) | ||
1491 | 1125 | goto err; | ||
1492 | 1126 | |||
1493 | 1127 | monitor->dispatch_fd = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK); | ||
1494 | 1128 | if (monitor->dispatch_fd < 0) | ||
1495 | 1129 | goto err; | ||
1496 | 1130 | /* make sure we wake up to dispatch the first time through */ | ||
1497 | 1131 | event_payload = 1; | ||
1498 | 1132 | ply_write (monitor->dispatch_fd, &event_payload, sizeof (event_payload)); | ||
1499 | 1133 | |||
1500 | 1134 | dispatch_event = ply_event_loop_watch_fd (monitor->loop, | ||
1501 | 1135 | monitor->dispatch_fd, | ||
1502 | 1136 | PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, | ||
1503 | 1137 | dispatch, NULL, monitor); | ||
1504 | 1138 | if (dispatch_event == NULL) | ||
1505 | 1139 | goto err; | ||
1506 | 1140 | |||
1507 | 1141 | dbus_connection_set_dispatch_status_function (monitor->connection, | ||
1508 | 1142 | dispatch_status, | ||
1509 | 1143 | monitor, NULL); | ||
1510 | 1144 | |||
1511 | 1145 | return true; | ||
1512 | 1146 | |||
1513 | 1147 | err: | ||
1514 | 1148 | dbus_connection_set_watch_functions (monitor->connection, | ||
1515 | 1149 | NULL, NULL, NULL, NULL, NULL); | ||
1516 | 1150 | dbus_connection_set_timeout_functions (monitor->connection, | ||
1517 | 1151 | NULL, NULL, NULL, NULL, NULL); | ||
1518 | 1152 | dbus_connection_set_dispatch_status_function (monitor->connection, | ||
1519 | 1153 | NULL, NULL, NULL); | ||
1520 | 1154 | if (dispatch_event != NULL) | ||
1521 | 1155 | ply_event_loop_stop_watching_fd (monitor->loop, dispatch_event); | ||
1522 | 1156 | if (monitor->dispatch_fd >= 0) | ||
1523 | 1157 | { | ||
1524 | 1158 | close (monitor->dispatch_fd); | ||
1525 | 1159 | monitor->dispatch_fd = -1; | ||
1526 | 1160 | } | ||
1527 | 1161 | monitor->loop = NULL; | ||
1528 | 1162 | return false; | ||
1529 | 1163 | } | ||
1530 | 1164 | |||
1531 | 1165 | void | ||
1532 | 1166 | ply_upstart_monitor_add_state_changed_handler (ply_upstart_monitor_t *monitor, | ||
1533 | 1167 | ply_upstart_monitor_state_changed_handler_t handler, | ||
1534 | 1168 | void *user_data) | ||
1535 | 1169 | { | ||
1536 | 1170 | monitor->state_changed_handler = handler; | ||
1537 | 1171 | monitor->state_changed_data = user_data; | ||
1538 | 1172 | } | ||
1539 | 1173 | |||
1540 | 1174 | void | ||
1541 | 1175 | ply_upstart_monitor_add_failed_handler (ply_upstart_monitor_t *monitor, | ||
1542 | 1176 | ply_upstart_monitor_failed_handler_t handler, | ||
1543 | 1177 | void *user_data) | ||
1544 | 1178 | { | ||
1545 | 1179 | monitor->failed_handler = handler; | ||
1546 | 1180 | monitor->failed_data = user_data; | ||
1547 | 1181 | } | ||
1548 | 1182 | /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ | ||
1549 | 0 | 1183 | ||
1550 | === added directory '.pc/ubuntu-logo-scale-factor-2.patch' | |||
1551 | === added directory '.pc/ubuntu-logo-scale-factor-2.patch/themes' | |||
1552 | === added directory '.pc/ubuntu-logo-scale-factor-2.patch/themes/ubuntu-logo' | |||
1553 | === added file '.pc/ubuntu-logo-scale-factor-2.patch/themes/ubuntu-logo/Makefile.am' | |||
1554 | --- .pc/ubuntu-logo-scale-factor-2.patch/themes/ubuntu-logo/Makefile.am 1970-01-01 00:00:00 +0000 | |||
1555 | +++ .pc/ubuntu-logo-scale-factor-2.patch/themes/ubuntu-logo/Makefile.am 2014-03-14 10:43:52 +0000 | |||
1556 | @@ -0,0 +1,23 @@ | |||
1557 | 1 | themedir = $(datadir)/plymouth/themes/ubuntu-logo | ||
1558 | 2 | nodist_theme_DATA = ubuntu-logo.plymouth | ||
1559 | 3 | dist_theme_DATA = ubuntu-logo.script \ | ||
1560 | 4 | ubuntu-logo.grub \ | ||
1561 | 5 | ubuntu_logo.png \ | ||
1562 | 6 | ubuntu_logo16.png \ | ||
1563 | 7 | password_field.png \ | ||
1564 | 8 | password_field16.png \ | ||
1565 | 9 | progress_dot_off.png \ | ||
1566 | 10 | progress_dot_off16.png \ | ||
1567 | 11 | progress_dot_on.png \ | ||
1568 | 12 | progress_dot_on16.png | ||
1569 | 13 | |||
1570 | 14 | |||
1571 | 15 | |||
1572 | 16 | MAINTAINERCLEANFILES = Makefile.in ubuntu-logo.plymouth | ||
1573 | 17 | CLEANFILES = ubuntu-logo.plymouth | ||
1574 | 18 | |||
1575 | 19 | ubuntu-logo.plymouth: $(srcdir)/ubuntu-logo.plymouth.in | ||
1576 | 20 | sed -e 's,[@]PLYMOUTH_THEME_PATH[@],$(PLYMOUTH_THEME_PATH),g' \ | ||
1577 | 21 | $(srcdir)/ubuntu-logo.plymouth.in > ubuntu-logo.plymouth | ||
1578 | 22 | |||
1579 | 23 | EXTRA_DIST = ubuntu-logo.plymouth.in | ||
1580 | 0 | 24 | ||
1581 | === added file '.pc/ubuntu-logo-scale-factor-2.patch/themes/ubuntu-logo/ubuntu-logo.plymouth.in' | |||
1582 | --- .pc/ubuntu-logo-scale-factor-2.patch/themes/ubuntu-logo/ubuntu-logo.plymouth.in 1970-01-01 00:00:00 +0000 | |||
1583 | +++ .pc/ubuntu-logo-scale-factor-2.patch/themes/ubuntu-logo/ubuntu-logo.plymouth.in 2014-03-14 10:43:52 +0000 | |||
1584 | @@ -0,0 +1,8 @@ | |||
1585 | 1 | [Plymouth Theme] | ||
1586 | 2 | Name=Ubuntu Logo | ||
1587 | 3 | Description=A theme that features a blank background with a logo. | ||
1588 | 4 | ModuleName=script | ||
1589 | 5 | |||
1590 | 6 | [script] | ||
1591 | 7 | ImageDir=@PLYMOUTH_THEME_PATH@/ubuntu-logo | ||
1592 | 8 | ScriptFile=@PLYMOUTH_THEME_PATH@/ubuntu-logo/ubuntu-logo.script | ||
1593 | 0 | 9 | ||
1594 | === added file '.pc/ubuntu-logo-scale-factor-2.patch/themes/ubuntu-logo/ubuntu-logo.script.in' | |||
1595 | === added directory '.pc/use-upstart-private-socket.patch' | |||
1596 | === added directory '.pc/use-upstart-private-socket.patch/src' | |||
1597 | === added directory '.pc/use-upstart-private-socket.patch/src/upstart-bridge' | |||
1598 | === added file '.pc/use-upstart-private-socket.patch/src/upstart-bridge/ply-upstart-monitor.c' | |||
1599 | --- .pc/use-upstart-private-socket.patch/src/upstart-bridge/ply-upstart-monitor.c 1970-01-01 00:00:00 +0000 | |||
1600 | +++ .pc/use-upstart-private-socket.patch/src/upstart-bridge/ply-upstart-monitor.c 2014-03-14 10:43:52 +0000 | |||
1601 | @@ -0,0 +1,1301 @@ | |||
1602 | 1 | /* ply-upstart-monitor.c - Upstart D-Bus monitor | ||
1603 | 2 | * | ||
1604 | 3 | * Copyright (C) 2010, 2011 Canonical Ltd. | ||
1605 | 4 | * | ||
1606 | 5 | * This program is free software; you can redistribute it and/or modify | ||
1607 | 6 | * it under the terms of the GNU General Public License as published by | ||
1608 | 7 | * the Free Software Foundation; either version 2, or (at your option) | ||
1609 | 8 | * any later version. | ||
1610 | 9 | * | ||
1611 | 10 | * This program is distributed in the hope that it will be useful, | ||
1612 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1613 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1614 | 13 | * GNU General Public License for more details. | ||
1615 | 14 | * | ||
1616 | 15 | * You should have received a copy of the GNU General Public License | ||
1617 | 16 | * along with this program; if not, write to the Free Software | ||
1618 | 17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
1619 | 18 | * 02111-1307, USA. | ||
1620 | 19 | * | ||
1621 | 20 | * Written by: Colin Watson <cjwatson@ubuntu.com> | ||
1622 | 21 | */ | ||
1623 | 22 | #include "config.h" | ||
1624 | 23 | #include "ply-upstart-monitor.h" | ||
1625 | 24 | |||
1626 | 25 | #include <assert.h> | ||
1627 | 26 | #include <stdbool.h> | ||
1628 | 27 | #include <stdlib.h> | ||
1629 | 28 | #include <stdio.h> | ||
1630 | 29 | #include <string.h> | ||
1631 | 30 | #include <sys/eventfd.h> | ||
1632 | 31 | |||
1633 | 32 | #include <dbus/dbus.h> | ||
1634 | 33 | |||
1635 | 34 | #include "ply-logger.h" | ||
1636 | 35 | #include "ply-event-loop.h" | ||
1637 | 36 | #include "ply-hashtable.h" | ||
1638 | 37 | #include "ply-list.h" | ||
1639 | 38 | #include "ply-utils.h" | ||
1640 | 39 | |||
1641 | 40 | typedef struct | ||
1642 | 41 | { | ||
1643 | 42 | ply_upstart_monitor_t *monitor; | ||
1644 | 43 | DBusTimeout *timeout; | ||
1645 | 44 | } ply_upstart_monitor_timeout_t; | ||
1646 | 45 | |||
1647 | 46 | struct _ply_upstart_monitor | ||
1648 | 47 | { | ||
1649 | 48 | DBusConnection *connection; | ||
1650 | 49 | char *owner; | ||
1651 | 50 | ply_event_loop_t *loop; | ||
1652 | 51 | ply_hashtable_t *jobs; | ||
1653 | 52 | ply_hashtable_t *all_instances; | ||
1654 | 53 | ply_upstart_monitor_state_changed_handler_t state_changed_handler; | ||
1655 | 54 | void *state_changed_data; | ||
1656 | 55 | ply_upstart_monitor_failed_handler_t failed_handler; | ||
1657 | 56 | void *failed_data; | ||
1658 | 57 | int dispatch_fd; | ||
1659 | 58 | }; | ||
1660 | 59 | |||
1661 | 60 | typedef struct | ||
1662 | 61 | { | ||
1663 | 62 | ply_upstart_monitor_t *monitor; | ||
1664 | 63 | ply_upstart_monitor_job_properties_t properties; | ||
1665 | 64 | ply_hashtable_t *instances; | ||
1666 | 65 | ply_list_t *pending_calls; | ||
1667 | 66 | } ply_upstart_monitor_job_t; | ||
1668 | 67 | |||
1669 | 68 | typedef struct | ||
1670 | 69 | { | ||
1671 | 70 | ply_upstart_monitor_job_t *job; | ||
1672 | 71 | ply_upstart_monitor_instance_properties_t properties; | ||
1673 | 72 | ply_list_t *pending_calls; | ||
1674 | 73 | uint32_t state_changed : 1; | ||
1675 | 74 | uint32_t call_failed : 1; | ||
1676 | 75 | } ply_upstart_monitor_instance_t; | ||
1677 | 76 | |||
1678 | 77 | #define UPSTART_SERVICE "com.ubuntu.Upstart" | ||
1679 | 78 | #define UPSTART_PATH "/com/ubuntu/Upstart" | ||
1680 | 79 | #define UPSTART_INTERFACE_0_6 "com.ubuntu.Upstart0_6" | ||
1681 | 80 | #define UPSTART_INTERFACE_0_6_JOB "com.ubuntu.Upstart0_6.Job" | ||
1682 | 81 | #define UPSTART_INTERFACE_0_6_INSTANCE "com.ubuntu.Upstart0_6.Instance" | ||
1683 | 82 | |||
1684 | 83 | /* Remove an entry from a hashtable, free the key, and return the data. */ | ||
1685 | 84 | static void * | ||
1686 | 85 | hashtable_remove_and_free_key (ply_hashtable_t *hashtable, | ||
1687 | 86 | const void *key) | ||
1688 | 87 | { | ||
1689 | 88 | void *reply_key, *reply_data; | ||
1690 | 89 | |||
1691 | 90 | if (!ply_hashtable_lookup_full (hashtable, (void *) key, | ||
1692 | 91 | &reply_key, &reply_data)) | ||
1693 | 92 | return NULL; | ||
1694 | 93 | ply_hashtable_remove (hashtable, (void *) key); | ||
1695 | 94 | free (reply_key); | ||
1696 | 95 | |||
1697 | 96 | return reply_data; | ||
1698 | 97 | } | ||
1699 | 98 | |||
1700 | 99 | /* We assume, in general, that Upstart responds to D-Bus messages in a | ||
1701 | 100 | * single thread, and that it processes messages on a given connection in | ||
1702 | 101 | * the order in which they were sent. Taken together, these assumptions | ||
1703 | 102 | * imply a kind of coherence: a Properties.GetAll reply received after a | ||
1704 | 103 | * StateChanged signal must have been computed entirely after the state | ||
1705 | 104 | * change. Thus, if this function returns false (properties have not been | ||
1706 | 105 | * fetched yet), it should be safe to record an event as call until such | ||
1707 | 106 | * time as the properties of the instance are known. | ||
1708 | 107 | */ | ||
1709 | 108 | static bool | ||
1710 | 109 | instance_is_initialized (ply_upstart_monitor_instance_t *instance) | ||
1711 | 110 | { | ||
1712 | 111 | /* Note that the job may not have a description. */ | ||
1713 | 112 | if (instance->job->properties.name && | ||
1714 | 113 | instance->properties.name && instance->properties.goal && | ||
1715 | 114 | instance->properties.state) | ||
1716 | 115 | return true; | ||
1717 | 116 | else | ||
1718 | 117 | return false; | ||
1719 | 118 | } | ||
1720 | 119 | |||
1721 | 120 | static void | ||
1722 | 121 | on_get_all_instance_properties_finished (DBusPendingCall *call, | ||
1723 | 122 | ply_upstart_monitor_instance_t *instance) | ||
1724 | 123 | { | ||
1725 | 124 | DBusMessage *reply; | ||
1726 | 125 | DBusMessageIter iter, array_iter, dict_iter, variant_iter; | ||
1727 | 126 | const char *key, *name, *goal, *state; | ||
1728 | 127 | ply_upstart_monitor_t *monitor; | ||
1729 | 128 | |||
1730 | 129 | assert (call != NULL); | ||
1731 | 130 | assert (instance != NULL); | ||
1732 | 131 | |||
1733 | 132 | reply = dbus_pending_call_steal_reply (call); | ||
1734 | 133 | if (reply == NULL) | ||
1735 | 134 | return; | ||
1736 | 135 | if (dbus_message_get_type (reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN) | ||
1737 | 136 | goto out; | ||
1738 | 137 | |||
1739 | 138 | dbus_message_iter_init (reply, &iter); | ||
1740 | 139 | if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) | ||
1741 | 140 | goto out; | ||
1742 | 141 | dbus_message_iter_recurse (&iter, &array_iter); | ||
1743 | 142 | |||
1744 | 143 | while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_DICT_ENTRY) | ||
1745 | 144 | { | ||
1746 | 145 | dbus_message_iter_recurse (&array_iter, &dict_iter); | ||
1747 | 146 | |||
1748 | 147 | if (dbus_message_iter_get_arg_type (&dict_iter) != DBUS_TYPE_STRING) | ||
1749 | 148 | goto next_item; | ||
1750 | 149 | |||
1751 | 150 | dbus_message_iter_get_basic (&dict_iter, &key); | ||
1752 | 151 | if (key == NULL) | ||
1753 | 152 | goto next_item; | ||
1754 | 153 | |||
1755 | 154 | dbus_message_iter_next (&dict_iter); | ||
1756 | 155 | if (dbus_message_iter_get_arg_type (&dict_iter) != DBUS_TYPE_VARIANT) | ||
1757 | 156 | goto next_item; | ||
1758 | 157 | dbus_message_iter_recurse (&dict_iter, &variant_iter); | ||
1759 | 158 | if (dbus_message_iter_get_arg_type (&variant_iter) != DBUS_TYPE_STRING) | ||
1760 | 159 | goto next_item; | ||
1761 | 160 | |||
1762 | 161 | if (strcmp (key, "name") == 0) | ||
1763 | 162 | { | ||
1764 | 163 | dbus_message_iter_get_basic (&variant_iter, &name); | ||
1765 | 164 | if (name != NULL) | ||
1766 | 165 | { | ||
1767 | 166 | ply_trace ("%s: name = '%s'", | ||
1768 | 167 | instance->job->properties.name, name); | ||
1769 | 168 | instance->properties.name = strdup (name); | ||
1770 | 169 | } | ||
1771 | 170 | } | ||
1772 | 171 | else if (strcmp (key, "goal") == 0) | ||
1773 | 172 | { | ||
1774 | 173 | dbus_message_iter_get_basic (&variant_iter, &goal); | ||
1775 | 174 | if (goal != NULL) | ||
1776 | 175 | { | ||
1777 | 176 | ply_trace ("%s: goal = '%s'", | ||
1778 | 177 | instance->job->properties.name, goal); | ||
1779 | 178 | instance->properties.goal = strdup (goal); | ||
1780 | 179 | } | ||
1781 | 180 | } | ||
1782 | 181 | else if (strcmp (key, "state") == 0) | ||
1783 | 182 | { | ||
1784 | 183 | dbus_message_iter_get_basic (&variant_iter, &state); | ||
1785 | 184 | if (state != NULL) | ||
1786 | 185 | { | ||
1787 | 186 | ply_trace ("%s: state = '%s'", | ||
1788 | 187 | instance->job->properties.name, state); | ||
1789 | 188 | instance->properties.state = strdup (state); | ||
1790 | 189 | } | ||
1791 | 190 | } | ||
1792 | 191 | |||
1793 | 192 | next_item: | ||
1794 | 193 | dbus_message_iter_next (&array_iter); | ||
1795 | 194 | } | ||
1796 | 195 | |||
1797 | 196 | out: | ||
1798 | 197 | dbus_message_unref (reply); | ||
1799 | 198 | |||
1800 | 199 | if (instance_is_initialized (instance)) | ||
1801 | 200 | { | ||
1802 | 201 | /* Process any call events. */ | ||
1803 | 202 | monitor = instance->job->monitor; | ||
1804 | 203 | |||
1805 | 204 | if (instance->state_changed && monitor->state_changed_handler) | ||
1806 | 205 | monitor->state_changed_handler (monitor->state_changed_data, NULL, | ||
1807 | 206 | &instance->job->properties, | ||
1808 | 207 | &instance->properties); | ||
1809 | 208 | instance->state_changed = false; | ||
1810 | 209 | |||
1811 | 210 | if (instance->call_failed && monitor->failed_handler) | ||
1812 | 211 | monitor->failed_handler (monitor->failed_data, | ||
1813 | 212 | &instance->job->properties, | ||
1814 | 213 | &instance->properties, | ||
1815 | 214 | instance->properties.failed); | ||
1816 | 215 | instance->call_failed = false; | ||
1817 | 216 | } | ||
1818 | 217 | } | ||
1819 | 218 | |||
1820 | 219 | static void | ||
1821 | 220 | on_get_all_job_properties_finished (DBusPendingCall *call, | ||
1822 | 221 | ply_upstart_monitor_job_t *job) | ||
1823 | 222 | { | ||
1824 | 223 | DBusMessage *reply; | ||
1825 | 224 | DBusMessageIter iter, array_iter, dict_iter, variant_iter; | ||
1826 | 225 | const char *key, *name, *description; | ||
1827 | 226 | dbus_uint32_t task; | ||
1828 | 227 | |||
1829 | 228 | assert (call != NULL); | ||
1830 | 229 | assert (job != NULL); | ||
1831 | 230 | |||
1832 | 231 | reply = dbus_pending_call_steal_reply (call); | ||
1833 | 232 | if (reply == NULL) | ||
1834 | 233 | return; | ||
1835 | 234 | if (dbus_message_get_type (reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN) | ||
1836 | 235 | goto out; | ||
1837 | 236 | |||
1838 | 237 | dbus_message_iter_init (reply, &iter); | ||
1839 | 238 | if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) | ||
1840 | 239 | goto out; | ||
1841 | 240 | dbus_message_iter_recurse (&iter, &array_iter); | ||
1842 | 241 | |||
1843 | 242 | while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_DICT_ENTRY) | ||
1844 | 243 | { | ||
1845 | 244 | dbus_message_iter_recurse (&array_iter, &dict_iter); | ||
1846 | 245 | |||
1847 | 246 | if (dbus_message_iter_get_arg_type (&dict_iter) != DBUS_TYPE_STRING) | ||
1848 | 247 | goto next_item; | ||
1849 | 248 | |||
1850 | 249 | dbus_message_iter_get_basic (&dict_iter, &key); | ||
1851 | 250 | if (key == NULL) | ||
1852 | 251 | goto next_item; | ||
1853 | 252 | |||
1854 | 253 | dbus_message_iter_next (&dict_iter); | ||
1855 | 254 | if (dbus_message_iter_get_arg_type (&dict_iter) != DBUS_TYPE_VARIANT) | ||
1856 | 255 | goto next_item; | ||
1857 | 256 | dbus_message_iter_recurse (&dict_iter, &variant_iter); | ||
1858 | 257 | |||
1859 | 258 | if (strcmp (key, "name") == 0) | ||
1860 | 259 | { | ||
1861 | 260 | if (dbus_message_iter_get_arg_type (&variant_iter) != | ||
1862 | 261 | DBUS_TYPE_STRING) | ||
1863 | 262 | goto next_item; | ||
1864 | 263 | dbus_message_iter_get_basic (&variant_iter, &name); | ||
1865 | 264 | if (name != NULL) | ||
1866 | 265 | { | ||
1867 | 266 | ply_trace ("name = '%s'", name); | ||
1868 | 267 | job->properties.name = strdup (name); | ||
1869 | 268 | } | ||
1870 | 269 | } | ||
1871 | 270 | else if (strcmp (key, "description") == 0) | ||
1872 | 271 | { | ||
1873 | 272 | if (dbus_message_iter_get_arg_type (&variant_iter) != | ||
1874 | 273 | DBUS_TYPE_STRING) | ||
1875 | 274 | goto next_item; | ||
1876 | 275 | dbus_message_iter_get_basic (&variant_iter, &description); | ||
1877 | 276 | if (description != NULL) | ||
1878 | 277 | { | ||
1879 | 278 | ply_trace ("description = '%s'", description); | ||
1880 | 279 | job->properties.description = strdup (description); | ||
1881 | 280 | } | ||
1882 | 281 | } | ||
1883 | 282 | else if (strcmp (key, "task") == 0) | ||
1884 | 283 | { | ||
1885 | 284 | if (dbus_message_iter_get_arg_type (&variant_iter) != | ||
1886 | 285 | DBUS_TYPE_BOOLEAN) | ||
1887 | 286 | goto next_item; | ||
1888 | 287 | dbus_message_iter_get_basic (&variant_iter, &task); | ||
1889 | 288 | ply_trace ("task = %s", task ? "TRUE" : "FALSE"); | ||
1890 | 289 | job->properties.is_task = task ? true : false; | ||
1891 | 290 | } | ||
1892 | 291 | |||
1893 | 292 | next_item: | ||
1894 | 293 | dbus_message_iter_next (&array_iter); | ||
1895 | 294 | } | ||
1896 | 295 | |||
1897 | 296 | out: | ||
1898 | 297 | dbus_message_unref (reply); | ||
1899 | 298 | } | ||
1900 | 299 | |||
1901 | 300 | static void | ||
1902 | 301 | remove_instance_internal (ply_upstart_monitor_job_t *job, const char *path) | ||
1903 | 302 | { | ||
1904 | 303 | ply_upstart_monitor_instance_t *instance; | ||
1905 | 304 | ply_list_node_t *node; | ||
1906 | 305 | |||
1907 | 306 | instance = hashtable_remove_and_free_key (job->instances, path); | ||
1908 | 307 | if (instance == NULL) | ||
1909 | 308 | return; | ||
1910 | 309 | hashtable_remove_and_free_key (job->monitor->all_instances, path); | ||
1911 | 310 | |||
1912 | 311 | node = ply_list_get_first_node (instance->pending_calls); | ||
1913 | 312 | while (node != NULL) | ||
1914 | 313 | { | ||
1915 | 314 | DBusPendingCall *call; | ||
1916 | 315 | ply_list_node_t *next_node; | ||
1917 | 316 | |||
1918 | 317 | call = ply_list_node_get_data (node); | ||
1919 | 318 | next_node = ply_list_get_next_node (instance->pending_calls, node); | ||
1920 | 319 | dbus_pending_call_cancel (call); | ||
1921 | 320 | dbus_pending_call_unref (call); | ||
1922 | 321 | node = next_node; | ||
1923 | 322 | } | ||
1924 | 323 | ply_list_free (instance->pending_calls); | ||
1925 | 324 | |||
1926 | 325 | free (instance->properties.name); | ||
1927 | 326 | free (instance->properties.goal); | ||
1928 | 327 | free (instance->properties.state); | ||
1929 | 328 | free (instance); | ||
1930 | 329 | } | ||
1931 | 330 | |||
1932 | 331 | static void | ||
1933 | 332 | add_instance (ply_upstart_monitor_job_t *job, | ||
1934 | 333 | const char *path) | ||
1935 | 334 | { | ||
1936 | 335 | ply_upstart_monitor_instance_t *instance; | ||
1937 | 336 | DBusMessage *message; | ||
1938 | 337 | const char *interface = UPSTART_INTERFACE_0_6_INSTANCE; | ||
1939 | 338 | DBusPendingCall *call; | ||
1940 | 339 | |||
1941 | 340 | ply_trace ("adding instance: %s", path); | ||
1942 | 341 | |||
1943 | 342 | remove_instance_internal (job, path); | ||
1944 | 343 | |||
1945 | 344 | instance = calloc (1, sizeof (ply_upstart_monitor_instance_t)); | ||
1946 | 345 | instance->job = job; | ||
1947 | 346 | instance->properties.name = NULL; | ||
1948 | 347 | instance->properties.goal = NULL; | ||
1949 | 348 | instance->properties.state = NULL; | ||
1950 | 349 | instance->properties.failed = false; | ||
1951 | 350 | instance->pending_calls = ply_list_new (); | ||
1952 | 351 | instance->state_changed = false; | ||
1953 | 352 | instance->call_failed = false; | ||
1954 | 353 | |||
1955 | 354 | /* Keep a hash of instances per job, to make InstanceRemoved handling | ||
1956 | 355 | * easy. | ||
1957 | 356 | */ | ||
1958 | 357 | ply_hashtable_insert (job->instances, strdup (path), instance); | ||
1959 | 358 | /* Keep a separate hash of all instances, to make StateChanged handling | ||
1960 | 359 | * easy. | ||
1961 | 360 | */ | ||
1962 | 361 | ply_hashtable_insert (job->monitor->all_instances, strdup (path), instance); | ||
1963 | 362 | |||
1964 | 363 | /* Ask Upstart for the name, goal, and state properties. */ | ||
1965 | 364 | ply_trace ("fetching properties of instance %s", path); | ||
1966 | 365 | message = dbus_message_new_method_call (UPSTART_SERVICE, path, | ||
1967 | 366 | DBUS_INTERFACE_PROPERTIES, "GetAll"); | ||
1968 | 367 | dbus_message_append_args (message, | ||
1969 | 368 | DBUS_TYPE_STRING, &interface, | ||
1970 | 369 | DBUS_TYPE_INVALID); | ||
1971 | 370 | dbus_connection_send_with_reply (job->monitor->connection, message, | ||
1972 | 371 | &call, -1); | ||
1973 | 372 | dbus_message_unref (message); | ||
1974 | 373 | if (call != NULL) | ||
1975 | 374 | { | ||
1976 | 375 | dbus_pending_call_set_notify (call, | ||
1977 | 376 | (DBusPendingCallNotifyFunction) | ||
1978 | 377 | on_get_all_instance_properties_finished, | ||
1979 | 378 | instance, NULL); | ||
1980 | 379 | ply_list_append_data (instance->pending_calls, call); | ||
1981 | 380 | } | ||
1982 | 381 | } | ||
1983 | 382 | |||
1984 | 383 | static void | ||
1985 | 384 | remove_instance (ply_upstart_monitor_job_t *job, | ||
1986 | 385 | const char *path) | ||
1987 | 386 | { | ||
1988 | 387 | ply_trace ("removing instance: %s", path); | ||
1989 | 388 | |||
1990 | 389 | remove_instance_internal (job, path); | ||
1991 | 390 | } | ||
1992 | 391 | |||
1993 | 392 | static void | ||
1994 | 393 | on_get_all_instances_finished (DBusPendingCall *call, | ||
1995 | 394 | ply_upstart_monitor_job_t *job) | ||
1996 | 395 | { | ||
1997 | 396 | DBusMessage *reply; | ||
1998 | 397 | DBusError error; | ||
1999 | 398 | char **instances; | ||
2000 | 399 | int n_instances, i; | ||
2001 | 400 | |||
2002 | 401 | assert (call != NULL); | ||
2003 | 402 | assert (job != NULL); | ||
2004 | 403 | |||
2005 | 404 | reply = dbus_pending_call_steal_reply (call); | ||
2006 | 405 | if (reply == NULL) | ||
2007 | 406 | return; | ||
2008 | 407 | if (dbus_message_get_type (reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN) | ||
2009 | 408 | goto out; | ||
2010 | 409 | |||
2011 | 410 | dbus_error_init (&error); | ||
2012 | 411 | dbus_message_get_args (reply, &error, | ||
2013 | 412 | DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, | ||
2014 | 413 | &instances, &n_instances, | ||
2015 | 414 | DBUS_TYPE_INVALID); | ||
2016 | 415 | if (dbus_error_is_set (&error)) | ||
2017 | 416 | goto out; | ||
2018 | 417 | dbus_error_free (&error); | ||
2019 | 418 | |||
2020 | 419 | for (i = 0; i < n_instances; ++i) | ||
2021 | 420 | add_instance (job, instances[i]); | ||
2022 | 421 | |||
2023 | 422 | dbus_free_string_array (instances); | ||
2024 | 423 | |||
2025 | 424 | out: | ||
2026 | 425 | dbus_message_unref (reply); | ||
2027 | 426 | } | ||
2028 | 427 | |||
2029 | 428 | static void | ||
2030 | 429 | free_job_instance (void *key, void *data, void *user_data) | ||
2031 | 430 | { | ||
2032 | 431 | const char *path = key; | ||
2033 | 432 | ply_upstart_monitor_instance_t *instance = data; | ||
2034 | 433 | ply_upstart_monitor_t *monitor = user_data; | ||
2035 | 434 | |||
2036 | 435 | assert (monitor != NULL); | ||
2037 | 436 | |||
2038 | 437 | if (instance == NULL) | ||
2039 | 438 | return; | ||
2040 | 439 | |||
2041 | 440 | hashtable_remove_and_free_key (monitor->all_instances, path); | ||
2042 | 441 | free (instance->properties.name); | ||
2043 | 442 | free (instance->properties.goal); | ||
2044 | 443 | free (instance->properties.state); | ||
2045 | 444 | free (instance); | ||
2046 | 445 | } | ||
2047 | 446 | |||
2048 | 447 | static void | ||
2049 | 448 | remove_job_internal (ply_upstart_monitor_t *monitor, const char *path) | ||
2050 | 449 | { | ||
2051 | 450 | ply_upstart_monitor_job_t *job; | ||
2052 | 451 | ply_list_node_t *node; | ||
2053 | 452 | |||
2054 | 453 | job = hashtable_remove_and_free_key (monitor->jobs, path); | ||
2055 | 454 | if (job == NULL) | ||
2056 | 455 | return; | ||
2057 | 456 | |||
2058 | 457 | node = ply_list_get_first_node (job->pending_calls); | ||
2059 | 458 | while (node != NULL) | ||
2060 | 459 | { | ||
2061 | 460 | DBusPendingCall *call; | ||
2062 | 461 | ply_list_node_t *next_node; | ||
2063 | 462 | |||
2064 | 463 | call = ply_list_node_get_data (node); | ||
2065 | 464 | next_node = ply_list_get_next_node (job->pending_calls, node); | ||
2066 | 465 | dbus_pending_call_cancel (call); | ||
2067 | 466 | dbus_pending_call_unref (call); | ||
2068 | 467 | node = next_node; | ||
2069 | 468 | } | ||
2070 | 469 | ply_list_free (job->pending_calls); | ||
2071 | 470 | |||
2072 | 471 | free (job->properties.name); | ||
2073 | 472 | free (job->properties.description); | ||
2074 | 473 | ply_hashtable_foreach (job->instances, free_job_instance, monitor); | ||
2075 | 474 | ply_hashtable_free (job->instances); | ||
2076 | 475 | free (job); | ||
2077 | 476 | } | ||
2078 | 477 | |||
2079 | 478 | static void | ||
2080 | 479 | add_job (ply_upstart_monitor_t *monitor, const char *path) | ||
2081 | 480 | { | ||
2082 | 481 | ply_upstart_monitor_job_t *job; | ||
2083 | 482 | DBusMessage *message; | ||
2084 | 483 | const char *interface = UPSTART_INTERFACE_0_6_JOB; | ||
2085 | 484 | DBusPendingCall *call; | ||
2086 | 485 | |||
2087 | 486 | ply_trace ("adding job: %s", path); | ||
2088 | 487 | |||
2089 | 488 | remove_job_internal (monitor, path); | ||
2090 | 489 | |||
2091 | 490 | job = calloc (1, sizeof (ply_upstart_monitor_job_t)); | ||
2092 | 491 | job->monitor = monitor; | ||
2093 | 492 | job->properties.name = NULL; | ||
2094 | 493 | job->properties.description = NULL; | ||
2095 | 494 | job->properties.is_task = false; | ||
2096 | 495 | job->instances = ply_hashtable_new (ply_hashtable_string_hash, | ||
2097 | 496 | ply_hashtable_string_compare); | ||
2098 | 497 | job->pending_calls = ply_list_new (); | ||
2099 | 498 | |||
2100 | 499 | ply_hashtable_insert (monitor->jobs, strdup (path), job); | ||
2101 | 500 | |||
2102 | 501 | /* Ask Upstart for the name and description properties. */ | ||
2103 | 502 | ply_trace ("fetching properties of job %s", path); | ||
2104 | 503 | message = dbus_message_new_method_call (UPSTART_SERVICE, path, | ||
2105 | 504 | DBUS_INTERFACE_PROPERTIES, "GetAll"); | ||
2106 | 505 | dbus_message_append_args (message, | ||
2107 | 506 | DBUS_TYPE_STRING, &interface, | ||
2108 | 507 | DBUS_TYPE_INVALID); | ||
2109 | 508 | dbus_connection_send_with_reply (monitor->connection, message, &call, -1); | ||
2110 | 509 | dbus_message_unref (message); | ||
2111 | 510 | if (call != NULL) | ||
2112 | 511 | { | ||
2113 | 512 | dbus_pending_call_set_notify (call, | ||
2114 | 513 | (DBusPendingCallNotifyFunction) | ||
2115 | 514 | on_get_all_job_properties_finished, | ||
2116 | 515 | job, | ||
2117 | 516 | NULL); | ||
2118 | 517 | ply_list_append_data (job->pending_calls, call); | ||
2119 | 518 | } | ||
2120 | 519 | |||
2121 | 520 | /* Ask Upstart for a list of all instances of this job. */ | ||
2122 | 521 | ply_trace ("calling GetAllInstances on job %s", path); | ||
2123 | 522 | message = dbus_message_new_method_call (UPSTART_SERVICE, path, | ||
2124 | 523 | UPSTART_INTERFACE_0_6_JOB, | ||
2125 | 524 | "GetAllInstances"); | ||
2126 | 525 | dbus_connection_send_with_reply (monitor->connection, message, &call, -1); | ||
2127 | 526 | dbus_message_unref (message); | ||
2128 | 527 | if (call != NULL) | ||
2129 | 528 | { | ||
2130 | 529 | dbus_pending_call_set_notify (call, | ||
2131 | 530 | (DBusPendingCallNotifyFunction) | ||
2132 | 531 | on_get_all_instances_finished, | ||
2133 | 532 | job, | ||
2134 | 533 | NULL); | ||
2135 | 534 | ply_list_append_data (job->pending_calls, call); | ||
2136 | 535 | } | ||
2137 | 536 | } | ||
2138 | 537 | |||
2139 | 538 | static void | ||
2140 | 539 | remove_job (ply_upstart_monitor_t *monitor, const char *path) | ||
2141 | 540 | { | ||
2142 | 541 | ply_trace ("removing job: %s", path); | ||
2143 | 542 | |||
2144 | 543 | remove_job_internal (monitor, path); | ||
2145 | 544 | } | ||
2146 | 545 | |||
2147 | 546 | static void | ||
2148 | 547 | on_get_all_jobs_finished (DBusPendingCall *call, | ||
2149 | 548 | ply_upstart_monitor_t *monitor) | ||
2150 | 549 | { | ||
2151 | 550 | DBusMessage *reply; | ||
2152 | 551 | DBusError error; | ||
2153 | 552 | char **jobs; | ||
2154 | 553 | int n_jobs, i; | ||
2155 | 554 | |||
2156 | 555 | assert (call != NULL); | ||
2157 | 556 | assert (monitor != NULL); | ||
2158 | 557 | |||
2159 | 558 | reply = dbus_pending_call_steal_reply (call); | ||
2160 | 559 | if (reply == NULL) | ||
2161 | 560 | return; | ||
2162 | 561 | if (dbus_message_get_type (reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN) | ||
2163 | 562 | goto out; | ||
2164 | 563 | |||
2165 | 564 | dbus_error_init (&error); | ||
2166 | 565 | dbus_message_get_args (reply, &error, | ||
2167 | 566 | DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, | ||
2168 | 567 | &jobs, &n_jobs, | ||
2169 | 568 | DBUS_TYPE_INVALID); | ||
2170 | 569 | if (dbus_error_is_set (&error)) | ||
2171 | 570 | goto out; | ||
2172 | 571 | dbus_error_free (&error); | ||
2173 | 572 | |||
2174 | 573 | for (i = 0; i < n_jobs; ++i) | ||
2175 | 574 | add_job (monitor, jobs[i]); | ||
2176 | 575 | |||
2177 | 576 | dbus_free_string_array (jobs); | ||
2178 | 577 | |||
2179 | 578 | out: | ||
2180 | 579 | dbus_message_unref (reply); | ||
2181 | 580 | } | ||
2182 | 581 | |||
2183 | 582 | static void | ||
2184 | 583 | on_get_name_owner_finished (DBusPendingCall *call, | ||
2185 | 584 | ply_upstart_monitor_t *monitor) | ||
2186 | 585 | { | ||
2187 | 586 | DBusMessage *reply, *message; | ||
2188 | 587 | DBusError error; | ||
2189 | 588 | const char *owner; | ||
2190 | 589 | |||
2191 | 590 | assert (call != NULL); | ||
2192 | 591 | assert (monitor != NULL); | ||
2193 | 592 | |||
2194 | 593 | reply = dbus_pending_call_steal_reply (call); | ||
2195 | 594 | if (reply == NULL) | ||
2196 | 595 | return; | ||
2197 | 596 | if (dbus_message_get_type (reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN) | ||
2198 | 597 | goto out; | ||
2199 | 598 | |||
2200 | 599 | dbus_error_init (&error); | ||
2201 | 600 | dbus_message_get_args (reply, &error, | ||
2202 | 601 | DBUS_TYPE_STRING, &owner, | ||
2203 | 602 | DBUS_TYPE_INVALID); | ||
2204 | 603 | if (dbus_error_is_set (&error)) | ||
2205 | 604 | goto out; | ||
2206 | 605 | dbus_error_free (&error); | ||
2207 | 606 | |||
2208 | 607 | ply_trace ("owner = '%s'", owner); | ||
2209 | 608 | |||
2210 | 609 | free (monitor->owner); | ||
2211 | 610 | monitor->owner = strdup (owner); | ||
2212 | 611 | |||
2213 | 612 | ply_trace ("calling GetAllJobs"); | ||
2214 | 613 | message = dbus_message_new_method_call (UPSTART_SERVICE, UPSTART_PATH, | ||
2215 | 614 | UPSTART_INTERFACE_0_6, | ||
2216 | 615 | "GetAllJobs"); | ||
2217 | 616 | dbus_connection_send_with_reply (monitor->connection, message, &call, -1); | ||
2218 | 617 | dbus_message_unref (message); | ||
2219 | 618 | if (call != NULL) | ||
2220 | 619 | dbus_pending_call_set_notify (call, | ||
2221 | 620 | (DBusPendingCallNotifyFunction) | ||
2222 | 621 | on_get_all_jobs_finished, | ||
2223 | 622 | monitor, NULL); | ||
2224 | 623 | |||
2225 | 624 | out: | ||
2226 | 625 | dbus_message_unref (reply); | ||
2227 | 626 | } | ||
2228 | 627 | |||
2229 | 628 | static DBusHandlerResult | ||
2230 | 629 | name_owner_changed_handler (DBusConnection *connection, | ||
2231 | 630 | DBusMessage *message, | ||
2232 | 631 | ply_upstart_monitor_t *monitor) | ||
2233 | 632 | { | ||
2234 | 633 | DBusError error; | ||
2235 | 634 | const char *name, *old_owner, *new_owner; | ||
2236 | 635 | |||
2237 | 636 | assert (connection != NULL); | ||
2238 | 637 | assert (message != NULL); | ||
2239 | 638 | assert (monitor != NULL); | ||
2240 | 639 | |||
2241 | 640 | dbus_error_init (&error); | ||
2242 | 641 | if (dbus_message_get_args (message, &error, | ||
2243 | 642 | DBUS_TYPE_STRING, &name, | ||
2244 | 643 | DBUS_TYPE_STRING, &old_owner, | ||
2245 | 644 | DBUS_TYPE_STRING, &new_owner, | ||
2246 | 645 | DBUS_TYPE_INVALID) && | ||
2247 | 646 | strcmp (name, UPSTART_SERVICE) == 0) | ||
2248 | 647 | { | ||
2249 | 648 | if (new_owner) | ||
2250 | 649 | ply_trace ("owner changed from '%s' to '%s'", old_owner, new_owner); | ||
2251 | 650 | else | ||
2252 | 651 | ply_trace ("owner left bus"); | ||
2253 | 652 | free (monitor->owner); | ||
2254 | 653 | monitor->owner = new_owner ? strdup (new_owner) : NULL; | ||
2255 | 654 | } | ||
2256 | 655 | |||
2257 | 656 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* let other handlers try */ | ||
2258 | 657 | } | ||
2259 | 658 | |||
2260 | 659 | static DBusHandlerResult | ||
2261 | 660 | job_added_handler (DBusConnection *connection, | ||
2262 | 661 | DBusMessage *message, | ||
2263 | 662 | ply_upstart_monitor_t *monitor) | ||
2264 | 663 | { | ||
2265 | 664 | DBusError error; | ||
2266 | 665 | const char *signal_path; | ||
2267 | 666 | |||
2268 | 667 | ply_trace ("got JobAdded"); | ||
2269 | 668 | dbus_error_init (&error); | ||
2270 | 669 | if (dbus_message_get_args (message, &error, | ||
2271 | 670 | DBUS_TYPE_OBJECT_PATH, &signal_path, | ||
2272 | 671 | DBUS_TYPE_INVALID)) | ||
2273 | 672 | add_job (monitor, signal_path); | ||
2274 | 673 | dbus_error_free (&error); | ||
2275 | 674 | return DBUS_HANDLER_RESULT_HANDLED; | ||
2276 | 675 | } | ||
2277 | 676 | |||
2278 | 677 | static DBusHandlerResult | ||
2279 | 678 | job_removed_handler (DBusConnection *connection, | ||
2280 | 679 | DBusMessage *message, | ||
2281 | 680 | ply_upstart_monitor_t *monitor) | ||
2282 | 681 | { | ||
2283 | 682 | DBusError error; | ||
2284 | 683 | const char *signal_path; | ||
2285 | 684 | |||
2286 | 685 | ply_trace ("got JobRemoved"); | ||
2287 | 686 | dbus_error_init (&error); | ||
2288 | 687 | if (dbus_message_get_args (message, &error, | ||
2289 | 688 | DBUS_TYPE_OBJECT_PATH, &signal_path, | ||
2290 | 689 | DBUS_TYPE_INVALID)) | ||
2291 | 690 | remove_job (monitor, signal_path); | ||
2292 | 691 | dbus_error_free (&error); | ||
2293 | 692 | return DBUS_HANDLER_RESULT_HANDLED; | ||
2294 | 693 | } | ||
2295 | 694 | |||
2296 | 695 | static DBusHandlerResult | ||
2297 | 696 | instance_added_handler (DBusConnection *connection, DBusMessage *message, | ||
2298 | 697 | ply_upstart_monitor_t *monitor, const char *path) | ||
2299 | 698 | { | ||
2300 | 699 | DBusError error; | ||
2301 | 700 | const char *signal_path; | ||
2302 | 701 | ply_upstart_monitor_job_t *job; | ||
2303 | 702 | |||
2304 | 703 | ply_trace ("got %s InstanceAdded", path); | ||
2305 | 704 | job = ply_hashtable_lookup (monitor->jobs, (void *) path); | ||
2306 | 705 | if (job != NULL) | ||
2307 | 706 | { | ||
2308 | 707 | dbus_error_init (&error); | ||
2309 | 708 | if (dbus_message_get_args (message, &error, | ||
2310 | 709 | DBUS_TYPE_OBJECT_PATH, &signal_path, | ||
2311 | 710 | DBUS_TYPE_INVALID)) | ||
2312 | 711 | add_instance (job, signal_path); | ||
2313 | 712 | dbus_error_free (&error); | ||
2314 | 713 | } | ||
2315 | 714 | return DBUS_HANDLER_RESULT_HANDLED; | ||
2316 | 715 | } | ||
2317 | 716 | |||
2318 | 717 | static DBusHandlerResult | ||
2319 | 718 | instance_removed_handler (DBusConnection *connection, DBusMessage *message, | ||
2320 | 719 | ply_upstart_monitor_t *monitor, const char *path) | ||
2321 | 720 | { | ||
2322 | 721 | DBusError error; | ||
2323 | 722 | const char *signal_path; | ||
2324 | 723 | ply_upstart_monitor_job_t *job; | ||
2325 | 724 | |||
2326 | 725 | ply_trace ("got %s InstanceRemoved", path); | ||
2327 | 726 | job = ply_hashtable_lookup (monitor->jobs, (void *) path); | ||
2328 | 727 | if (job != NULL) | ||
2329 | 728 | { | ||
2330 | 729 | dbus_error_init (&error); | ||
2331 | 730 | if (dbus_message_get_args (message, &error, | ||
2332 | 731 | DBUS_TYPE_OBJECT_PATH, &signal_path, | ||
2333 | 732 | DBUS_TYPE_INVALID)) | ||
2334 | 733 | remove_instance (job, signal_path); | ||
2335 | 734 | dbus_error_free (&error); | ||
2336 | 735 | } | ||
2337 | 736 | return DBUS_HANDLER_RESULT_HANDLED; | ||
2338 | 737 | } | ||
2339 | 738 | |||
2340 | 739 | static DBusHandlerResult | ||
2341 | 740 | goal_changed_handler (DBusConnection *connection, DBusMessage *message, | ||
2342 | 741 | ply_upstart_monitor_t *monitor, const char *path) | ||
2343 | 742 | { | ||
2344 | 743 | DBusError error; | ||
2345 | 744 | const char *goal; | ||
2346 | 745 | ply_upstart_monitor_instance_t *instance; | ||
2347 | 746 | char *old_goal; | ||
2348 | 747 | |||
2349 | 748 | ply_trace ("got %s GoalChanged", path); | ||
2350 | 749 | instance = ply_hashtable_lookup (monitor->all_instances, (void *) path); | ||
2351 | 750 | if (instance != NULL) | ||
2352 | 751 | { | ||
2353 | 752 | dbus_error_init (&error); | ||
2354 | 753 | if (dbus_message_get_args (message, &error, | ||
2355 | 754 | DBUS_TYPE_STRING, &goal, | ||
2356 | 755 | DBUS_TYPE_INVALID)) | ||
2357 | 756 | { | ||
2358 | 757 | old_goal = instance->properties.goal; | ||
2359 | 758 | instance->properties.goal = strdup (goal); | ||
2360 | 759 | ply_trace ("goal changed from '%s' to '%s'", old_goal, goal); | ||
2361 | 760 | free (old_goal); | ||
2362 | 761 | } | ||
2363 | 762 | dbus_error_free (&error); | ||
2364 | 763 | } | ||
2365 | 764 | return DBUS_HANDLER_RESULT_HANDLED; | ||
2366 | 765 | } | ||
2367 | 766 | |||
2368 | 767 | static DBusHandlerResult | ||
2369 | 768 | state_changed_handler (DBusConnection *connection, DBusMessage *message, | ||
2370 | 769 | ply_upstart_monitor_t *monitor, const char *path) | ||
2371 | 770 | { | ||
2372 | 771 | DBusError error; | ||
2373 | 772 | const char *state; | ||
2374 | 773 | ply_upstart_monitor_instance_t *instance; | ||
2375 | 774 | char *old_state; | ||
2376 | 775 | |||
2377 | 776 | ply_trace ("got %s StateChanged", path); | ||
2378 | 777 | instance = ply_hashtable_lookup (monitor->all_instances, (void *) path); | ||
2379 | 778 | if (instance != NULL) | ||
2380 | 779 | { | ||
2381 | 780 | dbus_error_init (&error); | ||
2382 | 781 | if (dbus_message_get_args (message, &error, | ||
2383 | 782 | DBUS_TYPE_STRING, &state, | ||
2384 | 783 | DBUS_TYPE_INVALID)) | ||
2385 | 784 | { | ||
2386 | 785 | old_state = instance->properties.state; | ||
2387 | 786 | instance->properties.state = strdup (state); | ||
2388 | 787 | ply_trace ("state changed from '%s' to '%s'", old_state, state); | ||
2389 | 788 | if (strcmp (state, "starting") == 0) | ||
2390 | 789 | { | ||
2391 | 790 | /* Clear any old failed information. */ | ||
2392 | 791 | instance->properties.failed = 0; | ||
2393 | 792 | instance->call_failed = false; | ||
2394 | 793 | } | ||
2395 | 794 | if (instance_is_initialized (instance)) | ||
2396 | 795 | { | ||
2397 | 796 | if (monitor->state_changed_handler) | ||
2398 | 797 | monitor->state_changed_handler (monitor->state_changed_data, | ||
2399 | 798 | old_state, | ||
2400 | 799 | &instance->job->properties, | ||
2401 | 800 | &instance->properties); | ||
2402 | 801 | } | ||
2403 | 802 | else | ||
2404 | 803 | instance->state_changed = true; | ||
2405 | 804 | free (old_state); | ||
2406 | 805 | } | ||
2407 | 806 | dbus_error_free (&error); | ||
2408 | 807 | } | ||
2409 | 808 | return DBUS_HANDLER_RESULT_HANDLED; | ||
2410 | 809 | } | ||
2411 | 810 | |||
2412 | 811 | static DBusHandlerResult | ||
2413 | 812 | failed_handler (DBusConnection *connection, DBusMessage *message, | ||
2414 | 813 | ply_upstart_monitor_t *monitor, const char *path) | ||
2415 | 814 | { | ||
2416 | 815 | DBusError error; | ||
2417 | 816 | ply_upstart_monitor_instance_t *instance; | ||
2418 | 817 | dbus_int32_t failed_status; | ||
2419 | 818 | |||
2420 | 819 | ply_trace ("got %s Failed", path); | ||
2421 | 820 | instance = ply_hashtable_lookup (monitor->all_instances, (void *) path); | ||
2422 | 821 | if (instance != NULL) | ||
2423 | 822 | { | ||
2424 | 823 | dbus_error_init (&error); | ||
2425 | 824 | if (dbus_message_get_args (message, &error, | ||
2426 | 825 | DBUS_TYPE_INT32, &failed_status, | ||
2427 | 826 | DBUS_TYPE_INVALID)) | ||
2428 | 827 | { | ||
2429 | 828 | instance->properties.failed = failed_status; | ||
2430 | 829 | if (instance_is_initialized (instance)) | ||
2431 | 830 | { | ||
2432 | 831 | if (monitor->failed_handler) | ||
2433 | 832 | monitor->failed_handler (monitor->failed_data, | ||
2434 | 833 | &instance->job->properties, | ||
2435 | 834 | &instance->properties, | ||
2436 | 835 | (int) failed_status); | ||
2437 | 836 | } | ||
2438 | 837 | else | ||
2439 | 838 | instance->call_failed = true; | ||
2440 | 839 | } | ||
2441 | 840 | dbus_error_free (&error); | ||
2442 | 841 | } | ||
2443 | 842 | return DBUS_HANDLER_RESULT_HANDLED; | ||
2444 | 843 | } | ||
2445 | 844 | |||
2446 | 845 | static DBusHandlerResult | ||
2447 | 846 | message_handler (DBusConnection *connection, DBusMessage *message, void *data) | ||
2448 | 847 | { | ||
2449 | 848 | ply_upstart_monitor_t *monitor = data; | ||
2450 | 849 | const char *path; | ||
2451 | 850 | |||
2452 | 851 | assert (connection != NULL); | ||
2453 | 852 | assert (message != NULL); | ||
2454 | 853 | assert (monitor != NULL); | ||
2455 | 854 | |||
2456 | 855 | path = dbus_message_get_path (message); | ||
2457 | 856 | if (path == NULL) | ||
2458 | 857 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
2459 | 858 | |||
2460 | 859 | if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, | ||
2461 | 860 | "NameOwnerChanged") && | ||
2462 | 861 | dbus_message_has_path (message, DBUS_PATH_DBUS) && | ||
2463 | 862 | dbus_message_has_sender (message, DBUS_SERVICE_DBUS)) | ||
2464 | 863 | return name_owner_changed_handler (connection, message, monitor); | ||
2465 | 864 | |||
2466 | 865 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6, | ||
2467 | 866 | "JobAdded")) | ||
2468 | 867 | return job_added_handler (connection, message, monitor); | ||
2469 | 868 | |||
2470 | 869 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6, | ||
2471 | 870 | "JobRemoved")) | ||
2472 | 871 | return job_removed_handler (connection, message, monitor); | ||
2473 | 872 | |||
2474 | 873 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6_JOB, | ||
2475 | 874 | "InstanceAdded")) | ||
2476 | 875 | return instance_added_handler (connection, message, monitor, path); | ||
2477 | 876 | |||
2478 | 877 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6_JOB, | ||
2479 | 878 | "InstanceRemoved")) | ||
2480 | 879 | return instance_removed_handler (connection, message, monitor, path); | ||
2481 | 880 | |||
2482 | 881 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6_INSTANCE, | ||
2483 | 882 | "GoalChanged")) | ||
2484 | 883 | return goal_changed_handler (connection, message, monitor, path); | ||
2485 | 884 | |||
2486 | 885 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6_INSTANCE, | ||
2487 | 886 | "StateChanged")) | ||
2488 | 887 | return state_changed_handler (connection, message, monitor, path); | ||
2489 | 888 | |||
2490 | 889 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6_INSTANCE, | ||
2491 | 890 | "Failed")) | ||
2492 | 891 | return failed_handler (connection, message, monitor, path); | ||
2493 | 892 | |||
2494 | 893 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
2495 | 894 | } | ||
2496 | 895 | |||
2497 | 896 | ply_upstart_monitor_t * | ||
2498 | 897 | ply_upstart_monitor_new (ply_event_loop_t *loop) | ||
2499 | 898 | { | ||
2500 | 899 | DBusError error; | ||
2501 | 900 | DBusConnection *connection; | ||
2502 | 901 | ply_upstart_monitor_t *monitor; | ||
2503 | 902 | char *rule; | ||
2504 | 903 | DBusMessage *message; | ||
2505 | 904 | const char *monitor_service = UPSTART_SERVICE; | ||
2506 | 905 | DBusPendingCall *call; | ||
2507 | 906 | |||
2508 | 907 | dbus_error_init (&error); | ||
2509 | 908 | |||
2510 | 909 | /* Get a connection to the system bus and set it up to listen for messages | ||
2511 | 910 | * from Upstart. | ||
2512 | 911 | */ | ||
2513 | 912 | connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); | ||
2514 | 913 | if (connection == NULL) | ||
2515 | 914 | { | ||
2516 | 915 | ply_error ("unable to connect to system bus: %s", error.message); | ||
2517 | 916 | dbus_error_free (&error); | ||
2518 | 917 | return NULL; | ||
2519 | 918 | } | ||
2520 | 919 | dbus_error_free (&error); | ||
2521 | 920 | |||
2522 | 921 | monitor = calloc (1, sizeof (ply_upstart_monitor_t)); | ||
2523 | 922 | monitor->connection = connection; | ||
2524 | 923 | monitor->loop = NULL; | ||
2525 | 924 | monitor->jobs = ply_hashtable_new (ply_hashtable_string_hash, | ||
2526 | 925 | ply_hashtable_string_compare); | ||
2527 | 926 | monitor->all_instances = ply_hashtable_new (ply_hashtable_string_hash, | ||
2528 | 927 | ply_hashtable_string_compare); | ||
2529 | 928 | monitor->state_changed_handler = NULL; | ||
2530 | 929 | monitor->state_changed_data = NULL; | ||
2531 | 930 | monitor->failed_handler = NULL; | ||
2532 | 931 | monitor->failed_data = NULL; | ||
2533 | 932 | monitor->dispatch_fd = -1; | ||
2534 | 933 | |||
2535 | 934 | if (!dbus_connection_add_filter (connection, message_handler, monitor, NULL)) | ||
2536 | 935 | { | ||
2537 | 936 | ply_error ("unable to add filter to system bus connection"); | ||
2538 | 937 | ply_upstart_monitor_free (monitor); | ||
2539 | 938 | return NULL; | ||
2540 | 939 | } | ||
2541 | 940 | |||
2542 | 941 | asprintf (&rule, "type='%s',sender='%s',path='%s'," | ||
2543 | 942 | "interface='%s',member='%s',arg0='%s'", | ||
2544 | 943 | "signal", DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, | ||
2545 | 944 | DBUS_INTERFACE_DBUS, "NameOwnerChanged", UPSTART_SERVICE); | ||
2546 | 945 | dbus_bus_add_match (connection, rule, &error); | ||
2547 | 946 | free (rule); | ||
2548 | 947 | if (dbus_error_is_set (&error)) | ||
2549 | 948 | { | ||
2550 | 949 | ply_error ("unable to add match rule to system bus connection: %s", | ||
2551 | 950 | error.message); | ||
2552 | 951 | ply_upstart_monitor_free (monitor); | ||
2553 | 952 | dbus_error_free (&error); | ||
2554 | 953 | return NULL; | ||
2555 | 954 | } | ||
2556 | 955 | |||
2557 | 956 | asprintf (&rule, "type='%s',sender='%s'", "signal", UPSTART_SERVICE); | ||
2558 | 957 | dbus_bus_add_match (connection, rule, &error); | ||
2559 | 958 | free (rule); | ||
2560 | 959 | if (dbus_error_is_set (&error)) | ||
2561 | 960 | { | ||
2562 | 961 | ply_error ("unable to add match rule to system bus connection: %s", | ||
2563 | 962 | error.message); | ||
2564 | 963 | ply_upstart_monitor_free (monitor); | ||
2565 | 964 | dbus_error_free (&error); | ||
2566 | 965 | return NULL; | ||
2567 | 966 | } | ||
2568 | 967 | |||
2569 | 968 | /* Start the state machine going: find out the current owner of the | ||
2570 | 969 | * well-known Upstart name. | ||
2571 | 970 | * Ignore errors: the worst case is that we don't get any messages back | ||
2572 | 971 | * and our state machine does nothing. | ||
2573 | 972 | */ | ||
2574 | 973 | ply_trace ("calling GetNameOwner"); | ||
2575 | 974 | message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, | ||
2576 | 975 | DBUS_INTERFACE_DBUS, "GetNameOwner"); | ||
2577 | 976 | dbus_message_append_args (message, | ||
2578 | 977 | DBUS_TYPE_STRING, &monitor_service, | ||
2579 | 978 | DBUS_TYPE_INVALID); | ||
2580 | 979 | dbus_connection_send_with_reply (connection, message, &call, -1); | ||
2581 | 980 | dbus_message_unref (message); | ||
2582 | 981 | if (call != NULL) | ||
2583 | 982 | dbus_pending_call_set_notify (call, | ||
2584 | 983 | (DBusPendingCallNotifyFunction) | ||
2585 | 984 | on_get_name_owner_finished, | ||
2586 | 985 | monitor, | ||
2587 | 986 | NULL); | ||
2588 | 987 | |||
2589 | 988 | if (loop != NULL) | ||
2590 | 989 | ply_upstart_monitor_connect_to_event_loop (monitor, loop); | ||
2591 | 990 | |||
2592 | 991 | return monitor; | ||
2593 | 992 | } | ||
2594 | 993 | |||
2595 | 994 | void | ||
2596 | 995 | ply_upstart_monitor_free (ply_upstart_monitor_t *monitor) | ||
2597 | 996 | { | ||
2598 | 997 | if (monitor == NULL) | ||
2599 | 998 | return; | ||
2600 | 999 | |||
2601 | 1000 | ply_hashtable_free (monitor->all_instances); | ||
2602 | 1001 | ply_hashtable_free (monitor->jobs); | ||
2603 | 1002 | dbus_connection_unref (monitor->connection); | ||
2604 | 1003 | if (monitor->dispatch_fd >= 0) | ||
2605 | 1004 | close (monitor->dispatch_fd); | ||
2606 | 1005 | free (monitor); | ||
2607 | 1006 | } | ||
2608 | 1007 | |||
2609 | 1008 | static void | ||
2610 | 1009 | read_watch_handler (void *data, int fd) | ||
2611 | 1010 | { | ||
2612 | 1011 | DBusWatch *watch = data; | ||
2613 | 1012 | |||
2614 | 1013 | assert (watch != NULL); | ||
2615 | 1014 | |||
2616 | 1015 | dbus_watch_handle (watch, DBUS_WATCH_READABLE); | ||
2617 | 1016 | } | ||
2618 | 1017 | |||
2619 | 1018 | static void | ||
2620 | 1019 | write_watch_handler (void *data, int fd) | ||
2621 | 1020 | { | ||
2622 | 1021 | DBusWatch *watch = data; | ||
2623 | 1022 | |||
2624 | 1023 | assert (watch != NULL); | ||
2625 | 1024 | |||
2626 | 1025 | dbus_watch_handle (watch, DBUS_WATCH_WRITABLE); | ||
2627 | 1026 | } | ||
2628 | 1027 | |||
2629 | 1028 | static dbus_bool_t | ||
2630 | 1029 | add_watch (DBusWatch *watch, void *data) | ||
2631 | 1030 | { | ||
2632 | 1031 | ply_upstart_monitor_t *monitor = data; | ||
2633 | 1032 | unsigned int flags; | ||
2634 | 1033 | int fd; | ||
2635 | 1034 | ply_event_loop_fd_status_t status; | ||
2636 | 1035 | ply_fd_watch_t *read_watch_event = NULL, *write_watch_event = NULL; | ||
2637 | 1036 | |||
2638 | 1037 | assert (monitor != NULL); | ||
2639 | 1038 | assert (watch != NULL); | ||
2640 | 1039 | |||
2641 | 1040 | if (!dbus_watch_get_enabled (watch)) | ||
2642 | 1041 | return TRUE; | ||
2643 | 1042 | |||
2644 | 1043 | assert (dbus_watch_get_data (watch) == NULL); | ||
2645 | 1044 | |||
2646 | 1045 | flags = dbus_watch_get_flags (watch); | ||
2647 | 1046 | fd = dbus_watch_get_unix_fd (watch); | ||
2648 | 1047 | |||
2649 | 1048 | if (flags & DBUS_WATCH_READABLE) | ||
2650 | 1049 | { | ||
2651 | 1050 | status = PLY_EVENT_LOOP_FD_STATUS_HAS_DATA; | ||
2652 | 1051 | read_watch_event = ply_event_loop_watch_fd (monitor->loop, fd, status, | ||
2653 | 1052 | read_watch_handler, NULL, | ||
2654 | 1053 | watch); | ||
2655 | 1054 | if (read_watch_event == NULL) | ||
2656 | 1055 | return FALSE; | ||
2657 | 1056 | dbus_watch_set_data (watch, read_watch_event, NULL); | ||
2658 | 1057 | } | ||
2659 | 1058 | |||
2660 | 1059 | if (flags & DBUS_WATCH_WRITABLE) | ||
2661 | 1060 | { | ||
2662 | 1061 | status = PLY_EVENT_LOOP_FD_STATUS_CAN_TAKE_DATA; | ||
2663 | 1062 | write_watch_event = ply_event_loop_watch_fd (monitor->loop, fd, status, | ||
2664 | 1063 | write_watch_handler, NULL, | ||
2665 | 1064 | watch); | ||
2666 | 1065 | if (write_watch_event == NULL) | ||
2667 | 1066 | { | ||
2668 | 1067 | if (read_watch_event != NULL) | ||
2669 | 1068 | ply_event_loop_stop_watching_fd (monitor->loop, read_watch_event); | ||
2670 | 1069 | return FALSE; | ||
2671 | 1070 | } | ||
2672 | 1071 | dbus_watch_set_data (watch, write_watch_event, NULL); | ||
2673 | 1072 | } | ||
2674 | 1073 | |||
2675 | 1074 | return TRUE; | ||
2676 | 1075 | } | ||
2677 | 1076 | |||
2678 | 1077 | static void | ||
2679 | 1078 | remove_watch (DBusWatch *watch, void *data) | ||
2680 | 1079 | { | ||
2681 | 1080 | ply_upstart_monitor_t *monitor = data; | ||
2682 | 1081 | ply_fd_watch_t *watch_event; | ||
2683 | 1082 | |||
2684 | 1083 | assert (monitor != NULL); | ||
2685 | 1084 | assert (watch != NULL); | ||
2686 | 1085 | |||
2687 | 1086 | watch_event = dbus_watch_get_data (watch); | ||
2688 | 1087 | if (watch_event == NULL) | ||
2689 | 1088 | return; | ||
2690 | 1089 | |||
2691 | 1090 | ply_event_loop_stop_watching_fd (monitor->loop, watch_event); | ||
2692 | 1091 | |||
2693 | 1092 | dbus_watch_set_data (watch, NULL, NULL); | ||
2694 | 1093 | } | ||
2695 | 1094 | |||
2696 | 1095 | static void | ||
2697 | 1096 | toggled_watch (DBusWatch *watch, void *data) | ||
2698 | 1097 | { | ||
2699 | 1098 | if (dbus_watch_get_enabled (watch)) | ||
2700 | 1099 | add_watch (watch, data); | ||
2701 | 1100 | else | ||
2702 | 1101 | remove_watch (watch, data); | ||
2703 | 1102 | } | ||
2704 | 1103 | |||
2705 | 1104 | static ply_upstart_monitor_timeout_t * | ||
2706 | 1105 | timeout_user_data_new (ply_upstart_monitor_t *monitor, DBusTimeout *timeout) | ||
2707 | 1106 | { | ||
2708 | 1107 | ply_upstart_monitor_timeout_t *monitor_timeout; | ||
2709 | 1108 | |||
2710 | 1109 | monitor_timeout = calloc (1, sizeof (ply_upstart_monitor_timeout_t)); | ||
2711 | 1110 | monitor_timeout->monitor = monitor; | ||
2712 | 1111 | monitor_timeout->timeout = timeout; | ||
2713 | 1112 | |||
2714 | 1113 | return monitor_timeout; | ||
2715 | 1114 | } | ||
2716 | 1115 | |||
2717 | 1116 | static void | ||
2718 | 1117 | timeout_user_data_free (void *data) | ||
2719 | 1118 | { | ||
2720 | 1119 | ply_upstart_monitor_timeout_t *monitor_timeout = data; | ||
2721 | 1120 | |||
2722 | 1121 | free (monitor_timeout); | ||
2723 | 1122 | } | ||
2724 | 1123 | |||
2725 | 1124 | static void | ||
2726 | 1125 | timeout_handler (void *data, ply_event_loop_t *loop) | ||
2727 | 1126 | { | ||
2728 | 1127 | ply_upstart_monitor_timeout_t *monitor_timeout = data; | ||
2729 | 1128 | |||
2730 | 1129 | assert (monitor_timeout != NULL); | ||
2731 | 1130 | |||
2732 | 1131 | dbus_timeout_handle (monitor_timeout->timeout); | ||
2733 | 1132 | } | ||
2734 | 1133 | |||
2735 | 1134 | static dbus_bool_t | ||
2736 | 1135 | add_timeout (DBusTimeout *timeout, void *data) | ||
2737 | 1136 | { | ||
2738 | 1137 | ply_upstart_monitor_t *monitor = data; | ||
2739 | 1138 | int interval; | ||
2740 | 1139 | ply_upstart_monitor_timeout_t *monitor_timeout; | ||
2741 | 1140 | |||
2742 | 1141 | assert (monitor != NULL); | ||
2743 | 1142 | assert (timeout != NULL); | ||
2744 | 1143 | |||
2745 | 1144 | if (!dbus_timeout_get_enabled (timeout)) | ||
2746 | 1145 | return TRUE; | ||
2747 | 1146 | |||
2748 | 1147 | interval = dbus_timeout_get_interval (timeout) * 1000; | ||
2749 | 1148 | |||
2750 | 1149 | monitor_timeout = timeout_user_data_new (monitor, timeout); | ||
2751 | 1150 | |||
2752 | 1151 | ply_event_loop_watch_for_timeout (monitor->loop, (double) interval, | ||
2753 | 1152 | timeout_handler, monitor_timeout); | ||
2754 | 1153 | |||
2755 | 1154 | dbus_timeout_set_data (timeout, monitor_timeout, timeout_user_data_free); | ||
2756 | 1155 | |||
2757 | 1156 | return TRUE; | ||
2758 | 1157 | } | ||
2759 | 1158 | |||
2760 | 1159 | static void | ||
2761 | 1160 | remove_timeout (DBusTimeout *timeout, void *data) | ||
2762 | 1161 | { | ||
2763 | 1162 | ply_upstart_monitor_t *monitor = data; | ||
2764 | 1163 | ply_upstart_monitor_timeout_t *monitor_timeout; | ||
2765 | 1164 | |||
2766 | 1165 | assert (monitor != NULL); | ||
2767 | 1166 | assert (timeout != NULL); | ||
2768 | 1167 | |||
2769 | 1168 | monitor_timeout = dbus_timeout_get_data (timeout); | ||
2770 | 1169 | if (monitor_timeout == NULL) | ||
2771 | 1170 | return; | ||
2772 | 1171 | |||
2773 | 1172 | ply_event_loop_stop_watching_for_timeout (monitor->loop, | ||
2774 | 1173 | timeout_handler, monitor_timeout); | ||
2775 | 1174 | |||
2776 | 1175 | dbus_timeout_set_data (timeout, NULL, NULL); | ||
2777 | 1176 | } | ||
2778 | 1177 | |||
2779 | 1178 | static void | ||
2780 | 1179 | toggled_timeout (DBusTimeout *timeout, void *data) | ||
2781 | 1180 | { | ||
2782 | 1181 | if (dbus_timeout_get_enabled (timeout)) | ||
2783 | 1182 | add_timeout (timeout, data); | ||
2784 | 1183 | else | ||
2785 | 1184 | remove_timeout (timeout, data); | ||
2786 | 1185 | } | ||
2787 | 1186 | |||
2788 | 1187 | static void | ||
2789 | 1188 | dispatch_status (DBusConnection *connection, DBusDispatchStatus new_status, | ||
2790 | 1189 | void *data) | ||
2791 | 1190 | { | ||
2792 | 1191 | ply_upstart_monitor_t *monitor = data; | ||
2793 | 1192 | uint64_t event_payload; | ||
2794 | 1193 | |||
2795 | 1194 | assert (monitor != NULL); | ||
2796 | 1195 | |||
2797 | 1196 | if (new_status != DBUS_DISPATCH_DATA_REMAINS) | ||
2798 | 1197 | return; | ||
2799 | 1198 | |||
2800 | 1199 | /* wake up event loop */ | ||
2801 | 1200 | event_payload = 1; | ||
2802 | 1201 | ply_write (monitor->dispatch_fd, &event_payload, sizeof (event_payload)); | ||
2803 | 1202 | } | ||
2804 | 1203 | |||
2805 | 1204 | static void | ||
2806 | 1205 | dispatch (void *data, int fd) | ||
2807 | 1206 | { | ||
2808 | 1207 | ply_upstart_monitor_t *monitor = data; | ||
2809 | 1208 | uint64_t event_payload; | ||
2810 | 1209 | |||
2811 | 1210 | assert (monitor != NULL); | ||
2812 | 1211 | |||
2813 | 1212 | /* reset eventfd to zero */ | ||
2814 | 1213 | ply_read (fd, &event_payload, sizeof (event_payload)); | ||
2815 | 1214 | |||
2816 | 1215 | while (dbus_connection_dispatch (monitor->connection) == | ||
2817 | 1216 | DBUS_DISPATCH_DATA_REMAINS) | ||
2818 | 1217 | ; | ||
2819 | 1218 | } | ||
2820 | 1219 | |||
2821 | 1220 | bool | ||
2822 | 1221 | ply_upstart_monitor_connect_to_event_loop (ply_upstart_monitor_t *monitor, | ||
2823 | 1222 | ply_event_loop_t *loop) | ||
2824 | 1223 | { | ||
2825 | 1224 | ply_fd_watch_t *dispatch_event = NULL; | ||
2826 | 1225 | uint64_t event_payload; | ||
2827 | 1226 | |||
2828 | 1227 | assert (monitor != NULL); | ||
2829 | 1228 | |||
2830 | 1229 | monitor->loop = loop; | ||
2831 | 1230 | monitor->dispatch_fd = -1; | ||
2832 | 1231 | |||
2833 | 1232 | if (!dbus_connection_set_watch_functions (monitor->connection, | ||
2834 | 1233 | add_watch, | ||
2835 | 1234 | remove_watch, | ||
2836 | 1235 | toggled_watch, | ||
2837 | 1236 | monitor, NULL)) | ||
2838 | 1237 | goto err; | ||
2839 | 1238 | |||
2840 | 1239 | if (!dbus_connection_set_timeout_functions (monitor->connection, | ||
2841 | 1240 | add_timeout, | ||
2842 | 1241 | remove_timeout, | ||
2843 | 1242 | toggled_timeout, | ||
2844 | 1243 | monitor, NULL)) | ||
2845 | 1244 | goto err; | ||
2846 | 1245 | |||
2847 | 1246 | monitor->dispatch_fd = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK); | ||
2848 | 1247 | if (monitor->dispatch_fd < 0) | ||
2849 | 1248 | goto err; | ||
2850 | 1249 | /* make sure we wake up to dispatch the first time through */ | ||
2851 | 1250 | event_payload = 1; | ||
2852 | 1251 | ply_write (monitor->dispatch_fd, &event_payload, sizeof (event_payload)); | ||
2853 | 1252 | |||
2854 | 1253 | dispatch_event = ply_event_loop_watch_fd (monitor->loop, | ||
2855 | 1254 | monitor->dispatch_fd, | ||
2856 | 1255 | PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, | ||
2857 | 1256 | dispatch, NULL, monitor); | ||
2858 | 1257 | if (dispatch_event == NULL) | ||
2859 | 1258 | goto err; | ||
2860 | 1259 | |||
2861 | 1260 | dbus_connection_set_dispatch_status_function (monitor->connection, | ||
2862 | 1261 | dispatch_status, | ||
2863 | 1262 | monitor, NULL); | ||
2864 | 1263 | |||
2865 | 1264 | return true; | ||
2866 | 1265 | |||
2867 | 1266 | err: | ||
2868 | 1267 | dbus_connection_set_watch_functions (monitor->connection, | ||
2869 | 1268 | NULL, NULL, NULL, NULL, NULL); | ||
2870 | 1269 | dbus_connection_set_timeout_functions (monitor->connection, | ||
2871 | 1270 | NULL, NULL, NULL, NULL, NULL); | ||
2872 | 1271 | dbus_connection_set_dispatch_status_function (monitor->connection, | ||
2873 | 1272 | NULL, NULL, NULL); | ||
2874 | 1273 | if (dispatch_event != NULL) | ||
2875 | 1274 | ply_event_loop_stop_watching_fd (monitor->loop, dispatch_event); | ||
2876 | 1275 | if (monitor->dispatch_fd >= 0) | ||
2877 | 1276 | { | ||
2878 | 1277 | close (monitor->dispatch_fd); | ||
2879 | 1278 | monitor->dispatch_fd = -1; | ||
2880 | 1279 | } | ||
2881 | 1280 | monitor->loop = NULL; | ||
2882 | 1281 | return false; | ||
2883 | 1282 | } | ||
2884 | 1283 | |||
2885 | 1284 | void | ||
2886 | 1285 | ply_upstart_monitor_add_state_changed_handler (ply_upstart_monitor_t *monitor, | ||
2887 | 1286 | ply_upstart_monitor_state_changed_handler_t handler, | ||
2888 | 1287 | void *user_data) | ||
2889 | 1288 | { | ||
2890 | 1289 | monitor->state_changed_handler = handler; | ||
2891 | 1290 | monitor->state_changed_data = user_data; | ||
2892 | 1291 | } | ||
2893 | 1292 | |||
2894 | 1293 | void | ||
2895 | 1294 | ply_upstart_monitor_add_failed_handler (ply_upstart_monitor_t *monitor, | ||
2896 | 1295 | ply_upstart_monitor_failed_handler_t handler, | ||
2897 | 1296 | void *user_data) | ||
2898 | 1297 | { | ||
2899 | 1298 | monitor->failed_handler = handler; | ||
2900 | 1299 | monitor->failed_data = user_data; | ||
2901 | 1300 | } | ||
2902 | 1301 | /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ | ||
2903 | 0 | 1302 | ||
2904 | === modified file 'debian/changelog' | |||
2905 | --- debian/changelog 2014-03-06 17:52:51 +0000 | |||
2906 | +++ debian/changelog 2014-03-14 10:43:52 +0000 | |||
2907 | @@ -1,10 +1,32 @@ | |||
2908 | 1 | plymouth (0.8.8-0ubuntu16) UNRELEASED; urgency=medium | 1 | plymouth (0.8.8-0ubuntu16) UNRELEASED; urgency=medium |
2909 | 2 | 2 | ||
2910 | 3 | [ Steve Langasek ] | ||
2911 | 3 | * Fix debian/patches/tty1-after-boot.patch: when we have multiple | 4 | * Fix debian/patches/tty1-after-boot.patch: when we have multiple |
2912 | 4 | non-default console options on the kernel commandline, | 5 | non-default console options on the kernel commandline, |
2913 | 5 | local_console_terminal will not be set, so we should avoid the resulting | 6 | local_console_terminal will not be set, so we should avoid the resulting |
2914 | 6 | assert. LP: #1160079, LP: #1235231. | 7 | assert. LP: #1160079, LP: #1235231. |
2915 | 7 | 8 | ||
2916 | 9 | [ Dimitri John Ledkov ] LP: #1292458 | ||
2917 | 10 | * debian/patches/use-upstart-private-socket.patch: instead of using | ||
2918 | 11 | system dbus, use private upstart socket in the plymouth-upstart-bridge. | ||
2919 | 12 | * debian/plymouth.plymouth-upstart-bridge.upstart: start | ||
2920 | 13 | plymouth-upstart-bridge on startup, and thus gather a more complete | ||
2921 | 14 | boot.log. | ||
2922 | 15 | * debian/patches/dont-bail-on-dummy-terms.patch: don't bail | ||
2923 | 16 | plymouth-upstart-bridge if TERM is not set and/or running on a dummy | ||
2924 | 17 | terminal, as we can run on those. This makes console-log useful in | ||
2925 | 18 | lxc-containers and actually contain messages from upstart jobs | ||
2926 | 19 | starting and stopping. | ||
2927 | 20 | * debian/patches/no-print-empty-description.patch: do not store | ||
2928 | 21 | description when dbus returns empty string, and thus stop printing | ||
2929 | 22 | empty "Starting... done" messages. LP: #1185560. | ||
2930 | 23 | * debian/plymouth.plymouth-upstart-bridge.upstart: update stop on | ||
2931 | 24 | conditions to stop when plymouth-shutdown finishes. | ||
2932 | 25 | * Make ubuntu-logo theme support scale factor, provide one plymouth | ||
2933 | 26 | theme with scale 1 and another with scale 2, until scale factor can be | ||
2934 | 27 | dynamically detected. | ||
2935 | 28 | * Mark plymouth-upstart-bridge to respawn. | ||
2936 | 29 | |||
2937 | 8 | -- Steve Langasek <steve.langasek@ubuntu.com> Tue, 04 Mar 2014 14:30:16 -0800 | 30 | -- Steve Langasek <steve.langasek@ubuntu.com> Tue, 04 Mar 2014 14:30:16 -0800 |
2938 | 9 | 31 | ||
2939 | 10 | plymouth (0.8.8-0ubuntu15) trusty; urgency=medium | 32 | plymouth (0.8.8-0ubuntu15) trusty; urgency=medium |
2940 | 11 | 33 | ||
2941 | === modified file 'debian/control' | |||
2942 | --- debian/control 2014-02-04 17:07:35 +0000 | |||
2943 | +++ debian/control 2014-03-14 10:43:52 +0000 | |||
2944 | @@ -178,7 +178,7 @@ | |||
2945 | 178 | 178 | ||
2946 | 179 | Package: plymouth-theme-ubuntu-logo | 179 | Package: plymouth-theme-ubuntu-logo |
2947 | 180 | Architecture: any | 180 | Architecture: any |
2949 | 181 | Depends: plymouth, plymouth-label, ${misc:Depends}, ${shlibs:Depends} | 181 | Depends: plymouth, plymouth-label, ttf-ubuntu-font-family, ${misc:Depends}, ${shlibs:Depends} |
2950 | 182 | Provides: plymouth-theme | 182 | Provides: plymouth-theme |
2951 | 183 | Replaces: plymouth (<< 0.8.1-1~) | 183 | Replaces: plymouth (<< 0.8.1-1~) |
2952 | 184 | Description: graphical boot animation and logger - ubuntu-logo theme | 184 | Description: graphical boot animation and logger - ubuntu-logo theme |
2953 | 185 | 185 | ||
2954 | === added file 'debian/patches/dont-bail-on-dummy-terms.patch' | |||
2955 | --- debian/patches/dont-bail-on-dummy-terms.patch 1970-01-01 00:00:00 +0000 | |||
2956 | +++ debian/patches/dont-bail-on-dummy-terms.patch 2014-03-14 10:43:52 +0000 | |||
2957 | @@ -0,0 +1,17 @@ | |||
2958 | 1 | Description: don't bail plymouth-upstart-bridge if TERM is not set | ||
2959 | 2 | and/or running on a dummy terminal, as we can run on those. | ||
2960 | 3 | Author: Dimitri John Ledkov <xnox@ubuntu.com> | ||
2961 | 4 | |||
2962 | 5 | --- a/src/upstart-bridge/plymouth-upstart-bridge.c | ||
2963 | 6 | +++ b/src/upstart-bridge/plymouth-upstart-bridge.c | ||
2964 | 7 | @@ -307,7 +307,9 @@ | ||
2965 | 8 | if (should_be_verbose && !ply_is_tracing ()) | ||
2966 | 9 | ply_toggle_tracing (); | ||
2967 | 10 | |||
2968 | 11 | - setupterm (NULL, STDOUT_FILENO, NULL); | ||
2969 | 12 | + /* Don't bail on dummy/hardcopy terminals */ | ||
2970 | 13 | + int errret=0; | ||
2971 | 14 | + setupterm (NULL, STDOUT_FILENO, &errret); | ||
2972 | 15 | |||
2973 | 16 | is_connected = ply_boot_client_connect (state.client, | ||
2974 | 17 | (ply_boot_client_disconnect_handler_t) | ||
2975 | 0 | 18 | ||
2976 | === added file 'debian/patches/no-print-empty-description.patch' | |||
2977 | --- debian/patches/no-print-empty-description.patch 1970-01-01 00:00:00 +0000 | |||
2978 | +++ debian/patches/no-print-empty-description.patch 2014-03-14 10:43:52 +0000 | |||
2979 | @@ -0,0 +1,14 @@ | |||
2980 | 1 | Description: do not store empty descriptions | ||
2981 | 2 | Author: Dimitri John Ledkov <xnox@ubuntu.com> | ||
2982 | 3 | |||
2983 | 4 | --- plymouth-0.8.8.orig/src/upstart-bridge/ply-upstart-monitor.c | ||
2984 | 5 | +++ plymouth-0.8.8/src/upstart-bridge/ply-upstart-monitor.c | ||
2985 | 6 | @@ -273,7 +273,7 @@ on_get_all_job_properties_finished (DBus | ||
2986 | 7 | DBUS_TYPE_STRING) | ||
2987 | 8 | goto next_item; | ||
2988 | 9 | dbus_message_iter_get_basic (&variant_iter, &description); | ||
2989 | 10 | - if (description != NULL) | ||
2990 | 11 | + if (description != NULL && description[0]) | ||
2991 | 12 | { | ||
2992 | 13 | ply_trace ("description = '%s'", description); | ||
2993 | 14 | job->properties.description = strdup (description); | ||
2994 | 0 | 15 | ||
2995 | === modified file 'debian/patches/series' | |||
2996 | --- debian/patches/series 2013-12-02 04:53:37 +0000 | |||
2997 | +++ debian/patches/series 2014-03-14 10:43:52 +0000 | |||
2998 | @@ -13,3 +13,7 @@ | |||
2999 | 13 | Miscellaneous-fixes-for-compiler-warnings.patch | 13 | Miscellaneous-fixes-for-compiler-warnings.patch |
3000 | 14 | autoreconf.patch | 14 | autoreconf.patch |
3001 | 15 | details-update-status.patch | 15 | details-update-status.patch |
3002 | 16 | use-upstart-private-socket.patch | ||
3003 | 17 | dont-bail-on-dummy-terms.patch | ||
3004 | 18 | no-print-empty-description.patch | ||
3005 | 19 | ubuntu-logo-scale-factor-2.patch | ||
3006 | 16 | 20 | ||
3007 | === added file 'debian/patches/ubuntu-logo-scale-factor-2.patch' | |||
3008 | --- debian/patches/ubuntu-logo-scale-factor-2.patch 1970-01-01 00:00:00 +0000 | |||
3009 | +++ debian/patches/ubuntu-logo-scale-factor-2.patch 2014-03-14 10:43:52 +0000 | |||
3010 | @@ -0,0 +1,1202 @@ | |||
3011 | 1 | Description: Make ubuntu-logo theme support scale factor, provide one plymouth | ||
3012 | 2 | theme with scale 1 and another with scale 2, until scale factor can be | ||
3013 | 3 | dynamically detected. | ||
3014 | 4 | Author: Dimitri John Ledkov <xnox@ubuntu.com> | ||
3015 | 5 | |||
3016 | 6 | --- a/themes/ubuntu-logo/Makefile.am | ||
3017 | 7 | +++ b/themes/ubuntu-logo/Makefile.am | ||
3018 | 8 | @@ -1,6 +1,7 @@ | ||
3019 | 9 | themedir = $(datadir)/plymouth/themes/ubuntu-logo | ||
3020 | 10 | -nodist_theme_DATA = ubuntu-logo.plymouth | ||
3021 | 11 | +nodist_theme_DATA = ubuntu-logo.plymouth ubuntu-logo-scale-2.plymouth | ||
3022 | 12 | dist_theme_DATA = ubuntu-logo.script \ | ||
3023 | 13 | + ubuntu-logo-scale-2.script \ | ||
3024 | 14 | ubuntu-logo.grub \ | ||
3025 | 15 | ubuntu_logo.png \ | ||
3026 | 16 | ubuntu_logo16.png \ | ||
3027 | 17 | @@ -13,11 +14,23 @@ | ||
3028 | 18 | |||
3029 | 19 | |||
3030 | 20 | |||
3031 | 21 | -MAINTAINERCLEANFILES = Makefile.in ubuntu-logo.plymouth | ||
3032 | 22 | -CLEANFILES = ubuntu-logo.plymouth | ||
3033 | 23 | +MAINTAINERCLEANFILES = Makefile.in ubuntu-logo.plymouth ubuntu-logo-scale-2.plymouth ubuntu-logo.script ubuntu-logo-scale-2.script | ||
3034 | 24 | +CLEANFILES = ubuntu-logo.plymouth ubuntu-logo-scale-2.plymouth ubuntu-logo.script ubuntu-logo-scale-2.script | ||
3035 | 25 | |||
3036 | 26 | ubuntu-logo.plymouth: $(srcdir)/ubuntu-logo.plymouth.in | ||
3037 | 27 | - sed -e 's,[@]PLYMOUTH_THEME_PATH[@],$(PLYMOUTH_THEME_PATH),g' \ | ||
3038 | 28 | + sed -e 's,[@]PLYMOUTH_THEME_PATH[@],$(PLYMOUTH_THEME_PATH),g;s,[@]EXTRA_NAME[@],,g;s,[@]SCRIPT_NAME[@],ubuntu-logo,g' \ | ||
3039 | 29 | $(srcdir)/ubuntu-logo.plymouth.in > ubuntu-logo.plymouth | ||
3040 | 30 | |||
3041 | 31 | -EXTRA_DIST = ubuntu-logo.plymouth.in | ||
3042 | 32 | +ubuntu-logo-scale-2.plymouth: $(srcdir)/ubuntu-logo.plymouth.in | ||
3043 | 33 | + sed -e 's,[@]PLYMOUTH_THEME_PATH[@],$(PLYMOUTH_THEME_PATH),g;s,[@]EXTRA_NAME[@],(Scale x2),g;s,[@]SCRIPT_NAME[@],ubuntu-logo-scale-2,g' \ | ||
3044 | 34 | + $(srcdir)/ubuntu-logo.plymouth.in > ubuntu-logo-scale-2.plymouth | ||
3045 | 35 | + | ||
3046 | 36 | +ubuntu-logo.script: $(srcdir)/ubuntu-logo.script.in | ||
3047 | 37 | + sed -e 's,[@]SCALEFACTOR[@],1,g' \ | ||
3048 | 38 | + $(srcdir)/ubuntu-logo.script.in > ubuntu-logo.script | ||
3049 | 39 | + | ||
3050 | 40 | +ubuntu-logo-scale-2.script: $(srcdir)/ubuntu-logo.script.in | ||
3051 | 41 | + sed -e 's,[@]SCALEFACTOR[@],2,g' \ | ||
3052 | 42 | + $(srcdir)/ubuntu-logo.script.in > ubuntu-logo-scale-2.script | ||
3053 | 43 | + | ||
3054 | 44 | +EXTRA_DIST = ubuntu-logo.plymouth.in ubuntu-logo.script.in | ||
3055 | 45 | --- a/themes/ubuntu-logo/ubuntu-logo.plymouth.in | ||
3056 | 46 | +++ b/themes/ubuntu-logo/ubuntu-logo.plymouth.in | ||
3057 | 47 | @@ -1,8 +1,8 @@ | ||
3058 | 48 | [Plymouth Theme] | ||
3059 | 49 | -Name=Ubuntu Logo | ||
3060 | 50 | +Name=Ubuntu Logo @EXTRA_NAME@ | ||
3061 | 51 | Description=A theme that features a blank background with a logo. | ||
3062 | 52 | ModuleName=script | ||
3063 | 53 | |||
3064 | 54 | [script] | ||
3065 | 55 | ImageDir=@PLYMOUTH_THEME_PATH@/ubuntu-logo | ||
3066 | 56 | -ScriptFile=@PLYMOUTH_THEME_PATH@/ubuntu-logo/ubuntu-logo.script | ||
3067 | 57 | +ScriptFile=@PLYMOUTH_THEME_PATH@/ubuntu-logo/@SCRIPT_NAME@.script | ||
3068 | 58 | --- /dev/null | ||
3069 | 59 | +++ b/themes/ubuntu-logo/ubuntu-logo.script.in | ||
3070 | 60 | @@ -0,0 +1,1142 @@ | ||
3071 | 61 | +# ubuntu-logo.script - boot splash plugin | ||
3072 | 62 | +# | ||
3073 | 63 | +# Copyright (C) 2009 Canonical Ltd. | ||
3074 | 64 | +# | ||
3075 | 65 | +# This program is free software; you can redistribute it and/or modify | ||
3076 | 66 | +# it under the terms of the GNU General Public License as published by | ||
3077 | 67 | +# the Free Software Foundation; either version 2, or (at your option) | ||
3078 | 68 | +# any later version. | ||
3079 | 69 | +# | ||
3080 | 70 | +# This program is distributed in the hope that it will be useful, | ||
3081 | 71 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3082 | 72 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3083 | 73 | +# GNU General Public License for more details. | ||
3084 | 74 | +# | ||
3085 | 75 | +# You should have received a copy of the GNU General Public License | ||
3086 | 76 | +# along with this program; if not, write to the Free Software | ||
3087 | 77 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
3088 | 78 | +# 02111-1307, USA. | ||
3089 | 79 | +# | ||
3090 | 80 | +# Written by: Alberto Milone <alberto.milone@canonical.com> | ||
3091 | 81 | +# | ||
3092 | 82 | +# Based on the example provided with the "script plugin" written by: | ||
3093 | 83 | +# Charlie Brej <cbrej@cs.man.ac.uk> | ||
3094 | 84 | +# | ||
3095 | 85 | +# Question stuff written by: Markus Waas <mail@markuswaas.de> | ||
3096 | 86 | +# | ||
3097 | 87 | +# | ||
3098 | 88 | + | ||
3099 | 89 | +# Set the text colour in (rgb / 256) | ||
3100 | 90 | +text_colour.red = 1.0; | ||
3101 | 91 | +text_colour.green = 1.0; | ||
3102 | 92 | +text_colour.blue = 1.0; | ||
3103 | 93 | + | ||
3104 | 94 | +# Tinted text #988592 | ||
3105 | 95 | +tinted_text_colour.red = 0.59; | ||
3106 | 96 | +tinted_text_colour.green = 0.52; | ||
3107 | 97 | +tinted_text_colour.blue = 0.57; | ||
3108 | 98 | + | ||
3109 | 99 | +# Action Text - #ffffff - RGB 255 255 255 | ||
3110 | 100 | +action_text_colour.red = 1.0; | ||
3111 | 101 | +action_text_colour.green = 1.0; | ||
3112 | 102 | +action_text_colour.blue = 1.0; | ||
3113 | 103 | + | ||
3114 | 104 | +# Orange - #ff4012 - RGB 255 64 18 | ||
3115 | 105 | +debugsprite = Sprite(); | ||
3116 | 106 | +debugsprite_bottom = Sprite(); | ||
3117 | 107 | +debugsprite_medium = Sprite(); | ||
3118 | 108 | + | ||
3119 | 109 | +# Ubuntu Font | ||
3120 | 110 | +ubuntufont = "Ubuntu 11"; | ||
3121 | 111 | +ubuntualignment = "center"; | ||
3122 | 112 | + | ||
3123 | 113 | +# Scale factor | ||
3124 | 114 | +scalefactor = @SCALEFACTOR@; | ||
3125 | 115 | + | ||
3126 | 116 | +# are we currently prompting for a password? | ||
3127 | 117 | +prompt_active = 0; | ||
3128 | 118 | + | ||
3129 | 119 | +# Generic scalable image loader | ||
3130 | 120 | +fun LoadScaleImage (imagepath) { | ||
3131 | 121 | + image = Image (imagepath); | ||
3132 | 122 | + image = image.Scale (image.GetWidth() * scalefactor, image.GetHeight() * scalefactor); | ||
3133 | 123 | + return image; | ||
3134 | 124 | +} | ||
3135 | 125 | + | ||
3136 | 126 | +# General purpose function to create text | ||
3137 | 127 | +fun WriteText (text, colour) { | ||
3138 | 128 | + image = Image.Text (text, colour.red, colour.green, colour.blue, color.alpha, ubuntufont, ubuntualignment); | ||
3139 | 129 | + image = image.Scale (image.GetWidth() * scalefactor, image.GetHeight() * scalefactor); | ||
3140 | 130 | + return image; | ||
3141 | 131 | +} | ||
3142 | 132 | + | ||
3143 | 133 | +fun ImageToText (text) { | ||
3144 | 134 | + image = WriteText (text, text_colour); | ||
3145 | 135 | + return image; | ||
3146 | 136 | +} | ||
3147 | 137 | + | ||
3148 | 138 | +fun ImageToTintedText (text) { | ||
3149 | 139 | + image = WriteText (text, tinted_text_colour); | ||
3150 | 140 | + return image; | ||
3151 | 141 | +} | ||
3152 | 142 | + | ||
3153 | 143 | +fun ImageToActionText (text) { | ||
3154 | 144 | + image = WriteText (text, action_text_colour); | ||
3155 | 145 | + return image; | ||
3156 | 146 | +} | ||
3157 | 147 | + | ||
3158 | 148 | +fun Debug(text) { | ||
3159 | 149 | + debugsprite.SetImage(ImageToText (text)); | ||
3160 | 150 | +} | ||
3161 | 151 | + | ||
3162 | 152 | +fun DebugBottom(text) { | ||
3163 | 153 | + debugsprite_bottom.SetImage(ImageToText (text)); | ||
3164 | 154 | + debugsprite_bottom.SetPosition(0, (Window.GetHeight (0) - 20), 1); | ||
3165 | 155 | +} | ||
3166 | 156 | + | ||
3167 | 157 | +fun DebugMedium(text) { | ||
3168 | 158 | + debugsprite_medium.SetImage(ImageToText (text)); | ||
3169 | 159 | + debugsprite_medium.SetPosition(0, (Window.GetHeight (0) - 60), 1); | ||
3170 | 160 | +} | ||
3171 | 161 | + | ||
3172 | 162 | +fun TextYOffset() { | ||
3173 | 163 | + local.y; | ||
3174 | 164 | + local.text_height; | ||
3175 | 165 | + local.min_height; | ||
3176 | 166 | + | ||
3177 | 167 | + # Put the 1st line below the logo + some spacing | ||
3178 | 168 | + y = logo.y + logo.height + (progress_indicator.bullet_height * 7 ); # + logo_spacing; | ||
3179 | 169 | + | ||
3180 | 170 | + text_height = first_line_height * 7.5; | ||
3181 | 171 | + | ||
3182 | 172 | + min_height = Window.GetHeight(); | ||
3183 | 173 | + if (y + text_height > min_height) | ||
3184 | 174 | + y = min_height - text_height; | ||
3185 | 175 | + | ||
3186 | 176 | + if (y < progress_indicator.y + progress_indicator.height) | ||
3187 | 177 | + return progress_indicator.y + progress_indicator.height; | ||
3188 | 178 | + return y; | ||
3189 | 179 | +} | ||
3190 | 180 | + | ||
3191 | 181 | +#------------------------------String functions------------------------------- | ||
3192 | 182 | + | ||
3193 | 183 | +# This is the equivalent for strstr() | ||
3194 | 184 | +fun StringString(string, substring) { | ||
3195 | 185 | + start = 0; | ||
3196 | 186 | + while (String(string).CharAt (start)) { | ||
3197 | 187 | + walk = 0; | ||
3198 | 188 | + while (String(substring).CharAt (walk) == String(string).CharAt (start + walk) ) { | ||
3199 | 189 | + walk++; | ||
3200 | 190 | + if (!String(substring).CharAt (walk)) return start; | ||
3201 | 191 | + } | ||
3202 | 192 | + start++; | ||
3203 | 193 | + } | ||
3204 | 194 | + | ||
3205 | 195 | + return NULL; | ||
3206 | 196 | +} | ||
3207 | 197 | + | ||
3208 | 198 | +fun StringLength (string) { | ||
3209 | 199 | + index = 0; | ||
3210 | 200 | + while (String(string).CharAt(index)) index++; | ||
3211 | 201 | + return index; | ||
3212 | 202 | +} | ||
3213 | 203 | + | ||
3214 | 204 | +fun StringCopy (source, beginning, end) { | ||
3215 | 205 | + local.destination = ""; | ||
3216 | 206 | + for (index = beginning; ( ( (end == NULL) || (index <= end) ) && (String(source).CharAt(index)) ); index++) { | ||
3217 | 207 | + local.destination += String(source).CharAt(index); | ||
3218 | 208 | + } | ||
3219 | 209 | + | ||
3220 | 210 | + return local.destination; | ||
3221 | 211 | +} | ||
3222 | 212 | + | ||
3223 | 213 | +fun StringReplace (source, pattern, replacement) { | ||
3224 | 214 | + local.found = StringString(source, pattern); | ||
3225 | 215 | + if (local.found == NULL) | ||
3226 | 216 | + return source; | ||
3227 | 217 | + | ||
3228 | 218 | + local.new_string = StringCopy (source, 0, local.found - 1) + | ||
3229 | 219 | + replacement + | ||
3230 | 220 | + StringCopy (source, local.found + StringLength(pattern), NULL); | ||
3231 | 221 | + | ||
3232 | 222 | + return local.new_string; | ||
3233 | 223 | +} | ||
3234 | 224 | + | ||
3235 | 225 | +# it makes sense to use it only for | ||
3236 | 226 | +# numbers up to 100 | ||
3237 | 227 | +fun StringToInteger (str) { | ||
3238 | 228 | + int = -1; | ||
3239 | 229 | + for (i=0; i<=100; i++) { | ||
3240 | 230 | + if (i+"" == str) { | ||
3241 | 231 | + int = i; | ||
3242 | 232 | + break; | ||
3243 | 233 | + } | ||
3244 | 234 | + } | ||
3245 | 235 | + return int; | ||
3246 | 236 | +} | ||
3247 | 237 | + | ||
3248 | 238 | +#----------------------------------------------------------------------------- | ||
3249 | 239 | +# Previous background colour | ||
3250 | 240 | +# #300a24 --> 0.19, 0.04, 0.14 | ||
3251 | 241 | +# New background colour | ||
3252 | 242 | +# #2c001e --> 0.16, 0.00, 0.12 | ||
3253 | 243 | +# | ||
3254 | 244 | +Window.SetBackgroundTopColor (0.16, 0.00, 0.12); # Nice colour on top of the screen fading to | ||
3255 | 245 | +Window.SetBackgroundBottomColor (0.16, 0.00, 0.12); # an equally nice colour on the bottom | ||
3256 | 246 | + | ||
3257 | 247 | +bits_per_pixel = Window.GetBitsPerPixel (); | ||
3258 | 248 | +if (bits_per_pixel == 4) { | ||
3259 | 249 | + logo_filename = "ubuntu_logo16.png"; | ||
3260 | 250 | + progress_dot_off_filename = "progress_dot_off16.png"; | ||
3261 | 251 | + progress_dot_on_filename = "progress_dot_on16.png"; | ||
3262 | 252 | + password_field_filename = "password_field16.png"; | ||
3263 | 253 | + question_field_filename = "password_field16.png"; | ||
3264 | 254 | +} else { | ||
3265 | 255 | + logo_filename = "ubuntu_logo.png"; | ||
3266 | 256 | + progress_dot_off_filename = "progress_dot_off.png"; | ||
3267 | 257 | + progress_dot_on_filename = "progress_dot_on.png"; | ||
3268 | 258 | + password_field_filename = "password_field.png"; | ||
3269 | 259 | + question_field_filename = "password_field.png"; | ||
3270 | 260 | +} | ||
3271 | 261 | + | ||
3272 | 262 | +logo.image = LoadScaleImage (logo_filename); | ||
3273 | 263 | +logo.sprite = Sprite (); | ||
3274 | 264 | +logo.sprite.SetImage (logo.image); | ||
3275 | 265 | +logo.width = logo.image.GetWidth (); | ||
3276 | 266 | +logo.height = logo.image.GetHeight (); | ||
3277 | 267 | +logo.x = Window.GetX () + Window.GetWidth () / 2 - logo.width / 2; | ||
3278 | 268 | +logo.y = Window.GetY () + Window.GetHeight () / 2 - logo.height; | ||
3279 | 269 | +logo.z = 1000; | ||
3280 | 270 | +logo.sprite.SetX (logo.x); | ||
3281 | 271 | +logo.sprite.SetY (logo.y); | ||
3282 | 272 | +logo.sprite.SetZ (logo.z); | ||
3283 | 273 | +logo.sprite.SetOpacity (1); | ||
3284 | 274 | + | ||
3285 | 275 | +# Spacing below the logo - in pixels | ||
3286 | 276 | +logo_spacing = logo.height * 4; | ||
3287 | 277 | + | ||
3288 | 278 | +message_notification[0].image = ImageToTintedText (""); | ||
3289 | 279 | +message_notification[1].image = ImageToTintedText (""); | ||
3290 | 280 | +fsck_notification.image = ImageToActionText (""); | ||
3291 | 281 | + | ||
3292 | 282 | +status = "normal"; | ||
3293 | 283 | + | ||
3294 | 284 | +progress_indicator.bullet_off = LoadScaleImage (progress_dot_off_filename); | ||
3295 | 285 | +progress_indicator.bullet_on = LoadScaleImage (progress_dot_on_filename); | ||
3296 | 286 | +progress_indicator.bullet_width = progress_indicator.bullet_off.GetWidth (); | ||
3297 | 287 | +progress_indicator.bullet_height = progress_indicator.bullet_off.GetHeight (); | ||
3298 | 288 | +progress_indicator.bullet_hspacing = progress_indicator.bullet_width * 1.1; | ||
3299 | 289 | +progress_indicator.width = progress_indicator.bullet_width * 5; | ||
3300 | 290 | +progress_indicator.height = progress_indicator.bullet_height; | ||
3301 | 291 | +progress_indicator.y = logo.y + logo.height + (logo.height / 4); | ||
3302 | 292 | +progress_indicator.x = Window.GetX () + Window.GetWidth () / 2 - progress_indicator.width / 2; # logo.x + 26; | ||
3303 | 293 | + | ||
3304 | 294 | +# use a fixed string with ascending and descending stems to calibrate the | ||
3305 | 295 | +# bounding box for the first message, so the messages below don't move up | ||
3306 | 296 | +# and down according to *their* height. | ||
3307 | 297 | +first_line_height = ImageToTintedText ("AfpqtM").GetHeight(); | ||
3308 | 298 | + | ||
3309 | 299 | +# if the user has a 640x480 or 800x600 display, we can't quite fit everything | ||
3310 | 300 | +# (including passphrase prompts) with the target spacing, so scoot the text up | ||
3311 | 301 | +# a bit if needed. | ||
3312 | 302 | +top_of_the_text = TextYOffset(); | ||
3313 | 303 | + | ||
3314 | 304 | +#-----------------------------------------Logo functions------------------------------ | ||
3315 | 305 | + | ||
3316 | 306 | +# Call this when updating the screen | ||
3317 | 307 | +fun draw_logo () { | ||
3318 | 308 | + logo.sprite.SetX (logo.x); | ||
3319 | 309 | + logo.sprite.SetY (logo.y); | ||
3320 | 310 | + logo.sprite.SetZ (logo.z); | ||
3321 | 311 | + logo.sprite.SetOpacity (1); | ||
3322 | 312 | +} | ||
3323 | 313 | + | ||
3324 | 314 | + | ||
3325 | 315 | +#-----------------------------------------Progress Indicator-------------------------- | ||
3326 | 316 | +fun set_progress_indicator () { | ||
3327 | 317 | + | ||
3328 | 318 | + | ||
3329 | 319 | + # Here we assume that we can store half bullets on each half of the screen | ||
3330 | 320 | + # together with some spacing | ||
3331 | 321 | + local.x = progress_indicator.x; | ||
3332 | 322 | + | ||
3333 | 323 | + for (index = 0; index <= 4; index++) { | ||
3334 | 324 | + # Set the "off" bullets | ||
3335 | 325 | + progress_indicator.bullets_off[index].sprite = Sprite (progress_indicator.bullet_off); | ||
3336 | 326 | + progress_indicator.bullets_off[index].sprite.SetPosition (local.x, progress_indicator.y, 1000); | ||
3337 | 327 | + progress_indicator.bullets_off[index].x = local.x; | ||
3338 | 328 | + progress_indicator.bullets_off[index].y = progress_indicator.y; | ||
3339 | 329 | + progress_indicator.bullets_off[index].sprite.SetOpacity (1); | ||
3340 | 330 | + | ||
3341 | 331 | + #local.debug_medium_string = "Progress indicator " + index + ": x = " + progress_indicator.bullets_off[index].x + | ||
3342 | 332 | + # ", y = " + progress_indicator.bullets_off[index].y + ", logo width = " + logo.width + | ||
3343 | 333 | + # ", logo height = " + logo.height + " " + screen_width + " " + screen_height; | ||
3344 | 334 | + # | ||
3345 | 335 | + #(index % 2) && DebugMedium (local.debug_medium_string) || DebugBottom (local.debug_medium_string); | ||
3346 | 336 | + | ||
3347 | 337 | + # Set the "on" bullets on top of the "off" bullets and make them transparent | ||
3348 | 338 | + progress_indicator.bullets_on[index].sprite = Sprite (progress_indicator.bullet_on); | ||
3349 | 339 | + progress_indicator.bullets_on[index].x = progress_indicator.bullets_off[index].x; | ||
3350 | 340 | + progress_indicator.bullets_on[index].y = progress_indicator.bullets_off[index].y; | ||
3351 | 341 | + progress_indicator.bullets_on[index].sprite.SetPosition (progress_indicator.bullets_on[index].x, progress_indicator.bullets_on[index].y, 10000); | ||
3352 | 342 | + | ||
3353 | 343 | + progress_indicator.bullets_on[index].sprite.SetOpacity (0); | ||
3354 | 344 | + | ||
3355 | 345 | + local.x += progress_indicator.bullet_hspacing; | ||
3356 | 346 | + } | ||
3357 | 347 | + #local.debug_string = "Progress indicator: x1 = " + progress_indicator.x + ", x2 = " + local.x + ", y = " + progress_indicator.y + | ||
3358 | 348 | + # ", x logo = " + logo.x + ", y logo = " + logo.y + ", indicator width = " + progress_indicator.width; | ||
3359 | 349 | + #Debug(progress_indicator.bullets_off[0].x); | ||
3360 | 350 | +} | ||
3361 | 351 | + | ||
3362 | 352 | + | ||
3363 | 353 | +# We have 2 bullets, one on top of the other: | ||
3364 | 354 | +# The white one is on top of the red one and the former should | ||
3365 | 355 | +# slowly fade so as to get a nice transition effect. | ||
3366 | 356 | +fun switch_on_bullet (bullets_off, bullets_on, bullet_number, opacity) { | ||
3367 | 357 | + local.x = bullets_on[bullet_number].x; | ||
3368 | 358 | + local.y = bullets_on[bullet_number].y; | ||
3369 | 359 | + local.z = bullets_on[bullet_number].z; | ||
3370 | 360 | + | ||
3371 | 361 | + # Hide the bullets which are off | ||
3372 | 362 | + bullets_off[bullet_number].sprite.SetOpacity (0); | ||
3373 | 363 | + | ||
3374 | 364 | + # Show the bullets which are on | ||
3375 | 365 | + bullets_on[bullet_number].sprite.SetPosition (local.x, local.y, local.z); | ||
3376 | 366 | + bullets_on[bullet_number].sprite.SetOpacity (opacity); | ||
3377 | 367 | + | ||
3378 | 368 | + # Bump the number of times we have switched on bullets | ||
3379 | 369 | + global.times_bullets_switched++; | ||
3380 | 370 | +} | ||
3381 | 371 | + | ||
3382 | 372 | +fun switch_off_bullets () { | ||
3383 | 373 | + # Debug("Switching off progress indicator"); | ||
3384 | 374 | + | ||
3385 | 375 | + set_progress_indicator (); | ||
3386 | 376 | + global.times_bullets_switched = 0; | ||
3387 | 377 | + global.on_off = 1; | ||
3388 | 378 | +} | ||
3389 | 379 | + | ||
3390 | 380 | +# This is something that we can call when we exit | ||
3391 | 381 | +fun switch_on_bullets () { | ||
3392 | 382 | + # Debug("Switching off progress indicator"); | ||
3393 | 383 | + if (!global.progress_indicator.bullets_on) set_progress_indicator (); | ||
3394 | 384 | + local = global.progress_indicator; | ||
3395 | 385 | + | ||
3396 | 386 | + for (index = 0; bullets_on[index]; index++) { | ||
3397 | 387 | + switch_on_bullet (bullets_off, bullets_on, index, 1.0); | ||
3398 | 388 | + } | ||
3399 | 389 | +} | ||
3400 | 390 | + | ||
3401 | 391 | + | ||
3402 | 392 | +# Implement in boot progress callback | ||
3403 | 393 | +fun animate_progress_indicator (progress, time) { | ||
3404 | 394 | + if (global.progress_time == NULL) { | ||
3405 | 395 | + global.progress_time = progress; #time; | ||
3406 | 396 | + switch_off_bullets (); | ||
3407 | 397 | + } | ||
3408 | 398 | + | ||
3409 | 399 | +# Debug ("progress = " + progress + ", time = " + time + " times switched = " + global.times_bullets_switched + " on_off " + global.on_off); | ||
3410 | 400 | + | ||
3411 | 401 | +# if (global.times_bullets_switched == NULL) | ||
3412 | 402 | +# global.times_bullets_switched = 5; | ||
3413 | 403 | + | ||
3414 | 404 | +# if (global.on_off == NULL) | ||
3415 | 405 | +# global.on_off = 0; | ||
3416 | 406 | + | ||
3417 | 407 | + if ((progress - global.progress_time) >= 1.0) { | ||
3418 | 408 | + global.progress_time = progress; | ||
3419 | 409 | + | ||
3420 | 410 | + if (global.times_bullets_switched == 5) { | ||
3421 | 411 | + # Change which bullets are switched on | ||
3422 | 412 | + # and which ones are switched off | ||
3423 | 413 | + global.on_off = !global.on_off; | ||
3424 | 414 | + global.times_bullets_switched = 0; | ||
3425 | 415 | + } | ||
3426 | 416 | + | ||
3427 | 417 | + if (global.on_off) { | ||
3428 | 418 | + switch_on_bullet (progress_indicator.bullets_off, progress_indicator.bullets_on, | ||
3429 | 419 | + global.times_bullets_switched, 1.0); | ||
3430 | 420 | + } | ||
3431 | 421 | + else { | ||
3432 | 422 | + switch_on_bullet (progress_indicator.bullets_on, progress_indicator.bullets_off, | ||
3433 | 423 | + global.times_bullets_switched, 1.0); | ||
3434 | 424 | + } | ||
3435 | 425 | + } | ||
3436 | 426 | + | ||
3437 | 427 | + | ||
3438 | 428 | + # Start setting bullets to "on" with translucency | ||
3439 | 429 | +# for (index = 0; index <= 5; index++) { | ||
3440 | 430 | +# opacity = 0.0; | ||
3441 | 431 | +# while (opacity <= 1.0) { | ||
3442 | 432 | +# switch_on_bullet (progress_indicator.bullets_off, progress_indicator.bullets_on, | ||
3443 | 433 | +# index, opacity); | ||
3444 | 434 | +# opacity += 0.1; | ||
3445 | 435 | +# } | ||
3446 | 436 | +# } | ||
3447 | 437 | +} | ||
3448 | 438 | + | ||
3449 | 439 | + | ||
3450 | 440 | +#-----------------------------------------Label utility functions--------------------- | ||
3451 | 441 | + | ||
3452 | 442 | +# label should be either a string or NULL | ||
3453 | 443 | +# Images for n lines will be created and returned as items of the | ||
3454 | 444 | +# message_label array | ||
3455 | 445 | +# | ||
3456 | 446 | +fun get_message_label (label, is_fake, is_action_line) { | ||
3457 | 447 | + # Debug("Get Label position"); | ||
3458 | 448 | + local.message_label; | ||
3459 | 449 | + | ||
3460 | 450 | + if (is_fake) | ||
3461 | 451 | + # Create a fake label so as to get the y coordinate of | ||
3462 | 452 | + # a standard-length label. | ||
3463 | 453 | + local.message_image = ImageToTintedText ("This is a fake message"); | ||
3464 | 454 | + else | ||
3465 | 455 | + local.message_image = (is_action_line) && ImageToActionText (label) || ImageToTintedText (label); | ||
3466 | 456 | + | ||
3467 | 457 | + message_label.width = message_image.GetWidth (); | ||
3468 | 458 | + message_label.height = message_image.GetHeight (); | ||
3469 | 459 | + | ||
3470 | 460 | + # Center the line horizontally | ||
3471 | 461 | + message_label.x = Window.GetX () + Window.GetWidth () / 2 - message_label.width / 2; | ||
3472 | 462 | + | ||
3473 | 463 | + message_label.y = top_of_the_text; | ||
3474 | 464 | + | ||
3475 | 465 | + # Put the 2nd line below the fsck line | ||
3476 | 466 | + if (is_action_line) { | ||
3477 | 467 | + local.fsck_label.y = message_label.y + (first_line_height + first_line_height / 2); | ||
3478 | 468 | + message_label.y = local.fsck_label.y + (first_line_height * 2); | ||
3479 | 469 | + } | ||
3480 | 470 | + | ||
3481 | 471 | + # Debug("action label x = " + message_label.x + " y = " + message_label.y ); | ||
3482 | 472 | + | ||
3483 | 473 | +# message_debug = "msg_x = " + message_label.x + " msg_y = " + message_label.y + | ||
3484 | 474 | +# "msg_width = " + message_label.width + " msg_height = " + | ||
3485 | 475 | +# message_label.height + " message = " + label; | ||
3486 | 476 | +# Debug(message_debug); | ||
3487 | 477 | + | ||
3488 | 478 | + return message_label; | ||
3489 | 479 | + | ||
3490 | 480 | +} | ||
3491 | 481 | + | ||
3492 | 482 | +# Create an fsck label and/or get its position | ||
3493 | 483 | +fun get_fsck_label (label, is_fake) { | ||
3494 | 484 | + # Debug("Get Label position"); | ||
3495 | 485 | + local.fsck_label = global.progress_label; | ||
3496 | 486 | + | ||
3497 | 487 | + if (is_fake) | ||
3498 | 488 | + fsck_label.image = ImageToTintedText ("This is a fake message"); | ||
3499 | 489 | + else | ||
3500 | 490 | + fsck_label.image = ImageToTintedText (label); | ||
3501 | 491 | + | ||
3502 | 492 | + fsck_label.width = fsck_label.image.GetWidth (); | ||
3503 | 493 | + fsck_label.height = fsck_label.image.GetHeight (); | ||
3504 | 494 | + | ||
3505 | 495 | + # Centre the label horizontally | ||
3506 | 496 | + fsck_label.x = Window.GetX () + Window.GetWidth () / 2 - fsck_label.width / 2; | ||
3507 | 497 | + | ||
3508 | 498 | + local.first_label = get_message_label (label, 1, 0); | ||
3509 | 499 | + | ||
3510 | 500 | + # Place the label below the 1st message line | ||
3511 | 501 | + fsck_label.y = local.first_label.y + local.first_label.height + (local.first_label.height / 2); | ||
3512 | 502 | + | ||
3513 | 503 | +# message_debug = "msg_x = " + fsck_label.x + " msg_y = " + fsck_label.y + | ||
3514 | 504 | +# "msg_width = " + fsck_label.width + " msg_height = " + | ||
3515 | 505 | +# fsck_label.height + " message = " + label; | ||
3516 | 506 | +# Debug(message_debug); | ||
3517 | 507 | + | ||
3518 | 508 | + return fsck_label; | ||
3519 | 509 | +} | ||
3520 | 510 | + | ||
3521 | 511 | +#-----------------------------------------Message stuff -------------------------------- | ||
3522 | 512 | +# | ||
3523 | 513 | + | ||
3524 | 514 | +# Set up a message label | ||
3525 | 515 | +# | ||
3526 | 516 | +# NOTE: this is called when doing something like 'plymouth message "hello world"' | ||
3527 | 517 | +# | ||
3528 | 518 | +fun setup_message (message_text, x, y, z, index) { | ||
3529 | 519 | + # Debug("Message setup"); | ||
3530 | 520 | + global.message_notification[index].image = (index) && ImageToActionText (message_text) || ImageToTintedText (message_text); | ||
3531 | 521 | + | ||
3532 | 522 | + # Set up the text message, if any | ||
3533 | 523 | + message_notification[index].x = x; | ||
3534 | 524 | + message_notification[index].y = y; | ||
3535 | 525 | + message_notification[index].z = z; | ||
3536 | 526 | + | ||
3537 | 527 | + message_notification[index].sprite = Sprite (); | ||
3538 | 528 | + message_notification[index].sprite.SetImage (message_notification[index].image); | ||
3539 | 529 | + message_notification[index].sprite.SetX (message_notification[index].x); | ||
3540 | 530 | + message_notification[index].sprite.SetY (message_notification[index].y); | ||
3541 | 531 | + message_notification[index].sprite.SetZ (message_notification[index].z); | ||
3542 | 532 | + | ||
3543 | 533 | +} | ||
3544 | 534 | + | ||
3545 | 535 | +fun show_message (index) { | ||
3546 | 536 | + if (global.message_notification[index].sprite) global.message_notification[index].sprite.SetOpacity(1); | ||
3547 | 537 | +} | ||
3548 | 538 | + | ||
3549 | 539 | +fun hide_message (index) { | ||
3550 | 540 | + if (global.message_notification[index].sprite) global.message_notification[index].sprite.SetOpacity(0); | ||
3551 | 541 | +} | ||
3552 | 542 | + | ||
3553 | 543 | + | ||
3554 | 544 | + | ||
3555 | 545 | + | ||
3556 | 546 | +# the callback function is called when new message should be displayed. | ||
3557 | 547 | +# First arg is message to display. | ||
3558 | 548 | +fun message_callback (message) | ||
3559 | 549 | +{ | ||
3560 | 550 | + # Debug("Message callback"); | ||
3561 | 551 | + is_fake = 0; | ||
3562 | 552 | + if (!message || (message == "")) is_fake = 1; | ||
3563 | 553 | + | ||
3564 | 554 | + local.substring = "keys:"; | ||
3565 | 555 | + | ||
3566 | 556 | + # Look for the "keys:" prefix | ||
3567 | 557 | + local.keys = StringString(message, local.substring); | ||
3568 | 558 | + | ||
3569 | 559 | + local.is_action_line = (keys != NULL); | ||
3570 | 560 | + #Debug("keys " + local.keys + " substring length = " + StringLength(local.substring)); | ||
3571 | 561 | + | ||
3572 | 562 | + # Get the message without the "keys:" prefix | ||
3573 | 563 | + if (keys != NULL) | ||
3574 | 564 | + message = StringCopy (message, keys + StringLength(local.substring), NULL); | ||
3575 | 565 | + | ||
3576 | 566 | + local.label.is_fake = is_fake; | ||
3577 | 567 | + label = get_message_label(message, is_fake, is_action_line); | ||
3578 | 568 | + label.z = 10000; | ||
3579 | 569 | + | ||
3580 | 570 | + setup_message (message, label.x, label.y, label.z, is_action_line); | ||
3581 | 571 | + if (prompt_active && local.is_action_line) | ||
3582 | 572 | + hide_message (is_action_line); | ||
3583 | 573 | + else | ||
3584 | 574 | + show_message (is_action_line); | ||
3585 | 575 | + | ||
3586 | 576 | +} | ||
3587 | 577 | + | ||
3588 | 578 | + | ||
3589 | 579 | +#-----------------------------------------Display Password stuff ----------------------- | ||
3590 | 580 | +# | ||
3591 | 581 | + | ||
3592 | 582 | +fun password_dialogue_setup (message_label) { | ||
3593 | 583 | + # Debug("Password dialog setup"); | ||
3594 | 584 | + | ||
3595 | 585 | + local.entry; | ||
3596 | 586 | + local.bullet_image; | ||
3597 | 587 | + bullet_image = LoadScaleImage (progress_dot_off_filename); | ||
3598 | 588 | + entry.image = LoadScaleImage (password_field_filename); | ||
3599 | 589 | + | ||
3600 | 590 | + # Hide the normal labels | ||
3601 | 591 | + prompt_active = 1; | ||
3602 | 592 | + if (message_notification[1].sprite) hide_message (1); | ||
3603 | 593 | + | ||
3604 | 594 | + # Set the prompt label | ||
3605 | 595 | + label = get_message_label(message_label, 0, 1); | ||
3606 | 596 | + label.z = 10000; | ||
3607 | 597 | + | ||
3608 | 598 | + setup_message (message_label, label.x, label.y, label.z, 2); | ||
3609 | 599 | + show_message (2); | ||
3610 | 600 | + | ||
3611 | 601 | + # Set up the text entry which contains the bullets | ||
3612 | 602 | + entry.sprite = Sprite (); | ||
3613 | 603 | + entry.sprite.SetImage (entry.image); | ||
3614 | 604 | + | ||
3615 | 605 | + # Centre the box horizontally | ||
3616 | 606 | + entry.x = Window.GetX () + Window.GetWidth () / 2 - entry.image.GetWidth () / 2; | ||
3617 | 607 | + | ||
3618 | 608 | + # Put the entry below the second label. | ||
3619 | 609 | + entry.y = message_notification[2].y + label.height; | ||
3620 | 610 | + | ||
3621 | 611 | + #Debug ("entry x = " + entry.x + ", y = " + entry.y); | ||
3622 | 612 | + entry.z = 10000; | ||
3623 | 613 | + entry.sprite.SetX (entry.x); | ||
3624 | 614 | + entry.sprite.SetY (entry.y); | ||
3625 | 615 | + entry.sprite.SetZ (entry.z); | ||
3626 | 616 | + | ||
3627 | 617 | + global.password_dialogue = local; | ||
3628 | 618 | +} | ||
3629 | 619 | + | ||
3630 | 620 | +fun password_dialogue_opacity (opacity) { | ||
3631 | 621 | + # Debug("Password dialog opacity"); | ||
3632 | 622 | + global.password_dialogue.opacity = opacity; | ||
3633 | 623 | + local = global.password_dialogue; | ||
3634 | 624 | + | ||
3635 | 625 | + # You can make the box translucent with a float | ||
3636 | 626 | + # entry.sprite.SetOpacity (0.3); | ||
3637 | 627 | + entry.sprite.SetOpacity (opacity); | ||
3638 | 628 | + label.sprite.SetOpacity (opacity); | ||
3639 | 629 | + | ||
3640 | 630 | + if (bullets) { | ||
3641 | 631 | + for (index = 0; bullets[index]; index++) { | ||
3642 | 632 | + bullets[index].sprite.SetOpacity (opacity); | ||
3643 | 633 | + } | ||
3644 | 634 | + } | ||
3645 | 635 | +} | ||
3646 | 636 | + | ||
3647 | 637 | + | ||
3648 | 638 | +# The callback function is called when the display should display a password dialogue. | ||
3649 | 639 | +# First arg is prompt string, the second is the number of bullets. | ||
3650 | 640 | +fun display_password_callback (prompt, bullets) { | ||
3651 | 641 | + # Debug("Password dialog setup"); | ||
3652 | 642 | + | ||
3653 | 643 | + global.status = "password"; | ||
3654 | 644 | + if (!global.password_dialogue) password_dialogue_setup(prompt); | ||
3655 | 645 | + password_dialogue_opacity (1); | ||
3656 | 646 | + bullet_width = password_dialogue.bullet_image.GetWidth(); | ||
3657 | 647 | + bullet_y = password_dialogue.entry.y + | ||
3658 | 648 | + password_dialogue.entry.image.GetHeight () / 2 - | ||
3659 | 649 | + password_dialogue.bullet_image.GetHeight () / 2; | ||
3660 | 650 | + margin = bullet_width; | ||
3661 | 651 | + spaces = Math.Int( (password_dialogue.entry.image.GetWidth () - (margin * 2) ) / ( 2 * bullet_width / 3 ) ); | ||
3662 | 652 | + #Debug ("spaces = " + spaces + ", bullets = " + bullets); | ||
3663 | 653 | + bullets_area.width = margin + spaces * ( 2 * bullet_width / 3); | ||
3664 | 654 | + bullets_area.x = Window.GetX () + Window.GetWidth () / 2 - bullets_area.width / 2; | ||
3665 | 655 | + #DebugBottom ("pwd_entry x = " + password_dialogue.entry.x + ", bullets_area.x = " + bullets_area.x + ", bullets_area.width = " + bullets_area.width); | ||
3666 | 656 | + if (bullets > spaces) | ||
3667 | 657 | + bullets = spaces; | ||
3668 | 658 | + for (index = 0; password_dialogue.bullets[index] || index < spaces ; index++){ | ||
3669 | 659 | + if (!password_dialogue.bullets[index]) { | ||
3670 | 660 | + password_dialogue.bullets[index].sprite = Sprite (); | ||
3671 | 661 | + password_dialogue.bullets[index].sprite.SetImage (password_dialogue.bullet_image); | ||
3672 | 662 | + password_dialogue.bullets[index].x = bullets_area.x + # password_dialogue.entry.x + margin + | ||
3673 | 663 | + index * ( 2 * bullet_width / 3 ) ; | ||
3674 | 664 | + password_dialogue.bullets[index].sprite.SetX (password_dialogue.bullets[index].x); | ||
3675 | 665 | + password_dialogue.bullets[index].y = bullet_y; | ||
3676 | 666 | + password_dialogue.bullets[index].sprite.SetY (password_dialogue.bullets[index].y); | ||
3677 | 667 | + password_dialogue.bullets[index].z = password_dialogue.entry.z + 100 - index; | ||
3678 | 668 | + password_dialogue.bullets[index].sprite.SetZ (password_dialogue.bullets[index].z); | ||
3679 | 669 | + } | ||
3680 | 670 | + | ||
3681 | 671 | + password_dialogue.bullets[index].sprite.SetOpacity (0); | ||
3682 | 672 | + | ||
3683 | 673 | + if (index < bullets ) { | ||
3684 | 674 | + password_dialogue.bullets[index].sprite.SetOpacity (1); | ||
3685 | 675 | + } | ||
3686 | 676 | + } | ||
3687 | 677 | +} | ||
3688 | 678 | + | ||
3689 | 679 | +Plymouth.SetDisplayPasswordFunction (display_password_callback); | ||
3690 | 680 | + | ||
3691 | 681 | +Plymouth.SetMessageFunction (message_callback); | ||
3692 | 682 | + | ||
3693 | 683 | +Plymouth.SetBootProgressFunction (animate_progress_indicator); | ||
3694 | 684 | + | ||
3695 | 685 | +# Plymouth.SetBootProgressFunction: the callback function is called with two numbers, the progress (between 0 and 1) and the time spent booting so far | ||
3696 | 686 | +# Plymouth.SetRootMountedFunction: the callback function is called when a new root is mounted | ||
3697 | 687 | +# Plymouth.SetKeyboardInputFunction: the callback function is called with a string containing a new character entered on the keyboard | ||
3698 | 688 | + | ||
3699 | 689 | +#----------------------------------------- FSCK Counter -------------------------------- | ||
3700 | 690 | + | ||
3701 | 691 | +# Initialise the counter | ||
3702 | 692 | +fun init_fsck_count () { | ||
3703 | 693 | + # The number of fsck checks in this cycle | ||
3704 | 694 | + global.counter.total = 0; | ||
3705 | 695 | + # The number of fsck checks already performed + the current one | ||
3706 | 696 | + global.counter.current = 1; | ||
3707 | 697 | + # The previous fsck | ||
3708 | 698 | + global.counter.last = 0; | ||
3709 | 699 | +} | ||
3710 | 700 | + | ||
3711 | 701 | +# Increase the total counter | ||
3712 | 702 | +fun increase_fsck_count () { | ||
3713 | 703 | + global.counter.total++; | ||
3714 | 704 | +} | ||
3715 | 705 | + | ||
3716 | 706 | +fun increase_current_fsck_count () { | ||
3717 | 707 | + global.counter.last = global.counter.current++; | ||
3718 | 708 | +} | ||
3719 | 709 | + | ||
3720 | 710 | +# Clear the counter | ||
3721 | 711 | +fun clear_fsck_count () { | ||
3722 | 712 | + global.counter = NULL; | ||
3723 | 713 | + init_fsck_count (); | ||
3724 | 714 | +} | ||
3725 | 715 | + | ||
3726 | 716 | +#----------------------------------------- Progress Label ------------------------------ | ||
3727 | 717 | + | ||
3728 | 718 | + | ||
3729 | 719 | +# Change the opacity level of a progress label | ||
3730 | 720 | +# | ||
3731 | 721 | +# opacity = 1 -> show | ||
3732 | 722 | +# opacity = 0 -> hide | ||
3733 | 723 | +# opacity = 0.3 (or any other float) -> translucent | ||
3734 | 724 | +# | ||
3735 | 725 | +fun set_progress_label_opacity (opacity) { | ||
3736 | 726 | + # the label | ||
3737 | 727 | + progress_label.sprite.SetOpacity (opacity); | ||
3738 | 728 | + | ||
3739 | 729 | + # Make the slot available again when hiding the bar | ||
3740 | 730 | + # So that another bar can take its place | ||
3741 | 731 | + if (opacity == 0) { | ||
3742 | 732 | + progress_label.is_available = 1; | ||
3743 | 733 | + progress_label.device = ""; | ||
3744 | 734 | + } | ||
3745 | 735 | +} | ||
3746 | 736 | + | ||
3747 | 737 | +# Set up a new Progress Bar | ||
3748 | 738 | +# | ||
3749 | 739 | +# TODO: Make it possible to reuse (rather than recreate) a bar | ||
3750 | 740 | +# if .is_available = 1. Ideally this would just reset the | ||
3751 | 741 | +# label, the associated | ||
3752 | 742 | +# device and the image size of the sprite. | ||
3753 | 743 | + | ||
3754 | 744 | +fun init_progress_label (device, status_string) { | ||
3755 | 745 | + # Make the slot unavailable | ||
3756 | 746 | + global.progress_label.is_available = 0; | ||
3757 | 747 | + progress_label.progress = 0; | ||
3758 | 748 | + progress_label.device = device; | ||
3759 | 749 | + progress_label.status_string = status_string; | ||
3760 | 750 | +} | ||
3761 | 751 | + | ||
3762 | 752 | +# See if the progress label is keeping track of the fsck | ||
3763 | 753 | +# of "device" | ||
3764 | 754 | +# | ||
3765 | 755 | +fun device_has_progress_label (device) { | ||
3766 | 756 | + #DebugBottom ("label device = " + progress_label.device + " checking device " + device); | ||
3767 | 757 | + return (progress_label.device == device); | ||
3768 | 758 | +} | ||
3769 | 759 | + | ||
3770 | 760 | +# Update the Progress bar which corresponds to index | ||
3771 | 761 | +# | ||
3772 | 762 | +fun update_progress_label (progress) { | ||
3773 | 763 | + # If progress is NULL then we just refresh the label. | ||
3774 | 764 | + # This happens when only counter.total has changed. | ||
3775 | 765 | + if (progress != NULL) { | ||
3776 | 766 | + progress_label.progress = progress; | ||
3777 | 767 | + | ||
3778 | 768 | + #Debug("device " + progress_label.device + " progress " + progress); | ||
3779 | 769 | + | ||
3780 | 770 | + # If progress >= 100% hide the label and make it available again | ||
3781 | 771 | + if (progress >= 100) { | ||
3782 | 772 | + set_progress_label_opacity (0); | ||
3783 | 773 | + | ||
3784 | 774 | + # See if we any other fsck check is complete | ||
3785 | 775 | + # and, if so, hide the progress bars and the labels | ||
3786 | 776 | + on_fsck_completed (); | ||
3787 | 777 | + | ||
3788 | 778 | + return 0; | ||
3789 | 779 | + } | ||
3790 | 780 | + } | ||
3791 | 781 | + # Update progress label here | ||
3792 | 782 | + # | ||
3793 | 783 | + # FIXME: the queue logic from this theme should really be moved into mountall | ||
3794 | 784 | + # instead of using string replacement to deal with localised strings. | ||
3795 | 785 | + label = StringReplace (progress_label.status_string[0], "%1$d", global.counter.current); | ||
3796 | 786 | + label = StringReplace (label, "%2$d", global.counter.total); | ||
3797 | 787 | + label = StringReplace (label, "%3$d", progress_label.progress); | ||
3798 | 788 | + label = StringReplace (label, "%%", "%"); | ||
3799 | 789 | + | ||
3800 | 790 | + progress_label = get_fsck_label (label, 0); | ||
3801 | 791 | + #progress_label.progress = progress; | ||
3802 | 792 | + | ||
3803 | 793 | + progress_label.sprite = Sprite (progress_label.image); | ||
3804 | 794 | + | ||
3805 | 795 | + # Set up the bar | ||
3806 | 796 | + progress_label.sprite.SetPosition(progress_label.x, progress_label.y, 1); | ||
3807 | 797 | + | ||
3808 | 798 | + set_progress_label_opacity (1); | ||
3809 | 799 | + | ||
3810 | 800 | +} | ||
3811 | 801 | + | ||
3812 | 802 | +# Refresh the label so as to update counters | ||
3813 | 803 | +fun refresh_progress_label () { | ||
3814 | 804 | + update_progress_label (NULL); | ||
3815 | 805 | +} | ||
3816 | 806 | + | ||
3817 | 807 | +#----------------------------------------- FSCK Queue ---------------------------------- | ||
3818 | 808 | + | ||
3819 | 809 | +# Initialise the fsck queue | ||
3820 | 810 | +fun init_queue () { | ||
3821 | 811 | + global.fsck_queue[0].device; | ||
3822 | 812 | + global.fsck_queue[0].progress; | ||
3823 | 813 | + global.fsck_queue.counter = 0; | ||
3824 | 814 | + global.fsck_queue.biggest_item = 0; | ||
3825 | 815 | +} | ||
3826 | 816 | + | ||
3827 | 817 | +fun clear_queue () { | ||
3828 | 818 | + global.fsck_queue = NULL; | ||
3829 | 819 | + init_queue (); | ||
3830 | 820 | +} | ||
3831 | 821 | + | ||
3832 | 822 | +# Return either the device index in the queue or -1 | ||
3833 | 823 | +fun queue_look_up_by_device (device) { | ||
3834 | 824 | + for (i=0; i <= fsck_queue.biggest_item; i++) { | ||
3835 | 825 | + if ((fsck_queue[i]) && (fsck_queue[i].device == device)) | ||
3836 | 826 | + return i; | ||
3837 | 827 | + } | ||
3838 | 828 | + return -1; | ||
3839 | 829 | +} | ||
3840 | 830 | + | ||
3841 | 831 | +# Keep track of an fsck process in the queue | ||
3842 | 832 | +fun add_fsck_to_queue (device, progress) { | ||
3843 | 833 | + # Look for an empty slot in the queue | ||
3844 | 834 | + for (i=0; global.fsck_queue[i].device; i++) { | ||
3845 | 835 | + continue; | ||
3846 | 836 | + } | ||
3847 | 837 | + local.index = i; | ||
3848 | 838 | + | ||
3849 | 839 | + # Set device and progress | ||
3850 | 840 | + global.fsck_queue[local.index].device = device; | ||
3851 | 841 | + global.fsck_queue[local.index].progress = progress; | ||
3852 | 842 | + | ||
3853 | 843 | + # Increase the queue counter | ||
3854 | 844 | + global.fsck_queue.counter++; | ||
3855 | 845 | + | ||
3856 | 846 | + # Update the max index of the array for iterations | ||
3857 | 847 | + if (local.index > global.fsck_queue.biggest_item) | ||
3858 | 848 | + global.fsck_queue.biggest_item = local.index; | ||
3859 | 849 | + | ||
3860 | 850 | + #DebugMedium ("Adding " + device + " at " + local.index); | ||
3861 | 851 | +} | ||
3862 | 852 | + | ||
3863 | 853 | +fun is_queue_empty () { | ||
3864 | 854 | + return (fsck_queue.counter == 0); | ||
3865 | 855 | +} | ||
3866 | 856 | + | ||
3867 | 857 | +fun is_progress_label_available () { | ||
3868 | 858 | + return (progress_label.is_available == 1); | ||
3869 | 859 | +} | ||
3870 | 860 | + | ||
3871 | 861 | + | ||
3872 | 862 | +# This should cover the case in which the fsck checks in | ||
3873 | 863 | +# the queue are completed before the ones showed in the | ||
3874 | 864 | +# progress label | ||
3875 | 865 | +fun on_queued_fsck_completed () { | ||
3876 | 866 | + if (!is_queue_empty ()) | ||
3877 | 867 | + return; | ||
3878 | 868 | + | ||
3879 | 869 | + # Hide the extra label, if any | ||
3880 | 870 | + #if (progress_bar.extra_label.sprite) | ||
3881 | 871 | + # progress_bar.extra_label.sprite.SetOpacity(0); | ||
3882 | 872 | +} | ||
3883 | 873 | + | ||
3884 | 874 | +fun remove_fsck_from_queue (index) { | ||
3885 | 875 | + # Free memory which was previously allocated for | ||
3886 | 876 | + # device and progress | ||
3887 | 877 | + global.fsck_queue[index].device = NULL; | ||
3888 | 878 | + global.fsck_queue[index].progress = NULL; | ||
3889 | 879 | + | ||
3890 | 880 | + # Decrease the queue counter | ||
3891 | 881 | + global.fsck_queue.counter--; | ||
3892 | 882 | + | ||
3893 | 883 | + # See if there are other processes in the queue | ||
3894 | 884 | + # if not, clear the extra_label | ||
3895 | 885 | + on_queued_fsck_completed (); | ||
3896 | 886 | +} | ||
3897 | 887 | + | ||
3898 | 888 | +fun on_fsck_completed () { | ||
3899 | 889 | + # We have moved on to tracking the next fsck | ||
3900 | 890 | + increase_current_fsck_count (); | ||
3901 | 891 | + | ||
3902 | 892 | + if (!is_progress_label_available ()) | ||
3903 | 893 | + return; | ||
3904 | 894 | + | ||
3905 | 895 | + if (!is_queue_empty ()) | ||
3906 | 896 | + return; | ||
3907 | 897 | + | ||
3908 | 898 | + # Hide the progress label | ||
3909 | 899 | + if (progress_label.sprite) | ||
3910 | 900 | + progress_label.sprite.SetOpacity (0); | ||
3911 | 901 | + | ||
3912 | 902 | + # Clear the queue | ||
3913 | 903 | + clear_queue (); | ||
3914 | 904 | + | ||
3915 | 905 | + # Clear the fsck counter | ||
3916 | 906 | + clear_fsck_count (); | ||
3917 | 907 | +} | ||
3918 | 908 | + | ||
3919 | 909 | +# Update an fsck process that we keep track of in the queue | ||
3920 | 910 | +fun update_progress_in_queue (index, device, progress) { | ||
3921 | 911 | + # If the fsck is complete, remove it from the queue | ||
3922 | 912 | + if (progress >= 100) { | ||
3923 | 913 | + remove_fsck_from_queue (index); | ||
3924 | 914 | + on_queued_fsck_completed (); | ||
3925 | 915 | + return; | ||
3926 | 916 | + } | ||
3927 | 917 | + | ||
3928 | 918 | + global.fsck_queue[index].device = device; | ||
3929 | 919 | + global.fsck_queue[index].progress = progress; | ||
3930 | 920 | + | ||
3931 | 921 | +} | ||
3932 | 922 | + | ||
3933 | 923 | +# TODO: Move it to some function | ||
3934 | 924 | +# Create an empty queue | ||
3935 | 925 | +#init_queue (); | ||
3936 | 926 | + | ||
3937 | 927 | + | ||
3938 | 928 | +#----------------------------------------- FSCK Functions ------------------------------ | ||
3939 | 929 | + | ||
3940 | 930 | + | ||
3941 | 931 | +# Either add a new bar for fsck checks or update an existing bar | ||
3942 | 932 | +# | ||
3943 | 933 | +# NOTE: no more than "progress_bar.max_number" bars are allowed | ||
3944 | 934 | +# | ||
3945 | 935 | +fun fsck_check (device, progress, status_string) { | ||
3946 | 936 | + | ||
3947 | 937 | + # The 1st time this will take place | ||
3948 | 938 | + if (!global.progress_label) { | ||
3949 | 939 | + # Increase the fsck counter | ||
3950 | 940 | + increase_fsck_count (); | ||
3951 | 941 | + | ||
3952 | 942 | + # Set up a new label for the check | ||
3953 | 943 | + init_progress_label (device, status_string); | ||
3954 | 944 | + update_progress_label (progress); | ||
3955 | 945 | + | ||
3956 | 946 | + return; | ||
3957 | 947 | + } | ||
3958 | 948 | + | ||
3959 | 949 | + | ||
3960 | 950 | + if (device_has_progress_label (device)) { | ||
3961 | 951 | + # Update the progress of the existing label | ||
3962 | 952 | + update_progress_label (progress); | ||
3963 | 953 | + } | ||
3964 | 954 | + else { | ||
3965 | 955 | + # See if there's already a slot in the queue for the device | ||
3966 | 956 | + local.queue_device_index = queue_look_up_by_device(device); | ||
3967 | 957 | + | ||
3968 | 958 | + # See if the progress_label is available | ||
3969 | 959 | + if (progress_label.is_available) { | ||
3970 | 960 | + | ||
3971 | 961 | +# local.my_string = "available index " + local.available_index + " progress_bar counter is " + progress_bar.counter; | ||
3972 | 962 | +# Debug(local.my_string); | ||
3973 | 963 | + | ||
3974 | 964 | + | ||
3975 | 965 | + # If the fsck check for the device was in the queue, then | ||
3976 | 966 | + # remove it from the queue | ||
3977 | 967 | + if (local.queue_device_index >= 0) { | ||
3978 | 968 | + remove_fsck_from_queue (index); | ||
3979 | 969 | + } | ||
3980 | 970 | + else { | ||
3981 | 971 | + # Increase the fsck counter | ||
3982 | 972 | + increase_fsck_count (); | ||
3983 | 973 | + } | ||
3984 | 974 | + | ||
3985 | 975 | +# local.my_string += local.message; | ||
3986 | 976 | + #Debug("setting new label for device " + device + " progress " + progress); | ||
3987 | 977 | + | ||
3988 | 978 | + # Set up a new label for the check | ||
3989 | 979 | + init_progress_label (device, status_string); | ||
3990 | 980 | + update_progress_label (progress); | ||
3991 | 981 | + | ||
3992 | 982 | + } | ||
3993 | 983 | + # If the progress_label is not available | ||
3994 | 984 | + else { | ||
3995 | 985 | + | ||
3996 | 986 | + # If the fsck check for the device is already in the queue | ||
3997 | 987 | + # just update its progress in the queue | ||
3998 | 988 | + if (local.queue_device_index >= 0) { | ||
3999 | 989 | + #DebugMedium("Updating queue at " + local.queue_device_index + " for device " + device); | ||
4000 | 990 | + update_progress_in_queue (local.queue_device_index, device, progress); | ||
4001 | 991 | + } | ||
4002 | 992 | + # Otherwise add the check to the queue | ||
4003 | 993 | + else { | ||
4004 | 994 | + #DebugMedium("Adding device " + device + " to queue at " + local.queue_device_index); | ||
4005 | 995 | + add_fsck_to_queue (device, progress); | ||
4006 | 996 | + | ||
4007 | 997 | + # Increase the fsck counter | ||
4008 | 998 | + increase_fsck_count (); | ||
4009 | 999 | + | ||
4010 | 1000 | + refresh_progress_label (); | ||
4011 | 1001 | + } | ||
4012 | 1002 | + | ||
4013 | 1003 | + } | ||
4014 | 1004 | + } | ||
4015 | 1005 | + | ||
4016 | 1006 | +# if (!is_queue_empty ()) { | ||
4017 | 1007 | +# DebugBottom("Extra label for "+ device); | ||
4018 | 1008 | + #} | ||
4019 | 1009 | +# else { | ||
4020 | 1010 | +# DebugBottom("No extra label for " + device + ". 1st Device in the queue "+ fsck_queue[0].device + " counter = " + global.fsck_queue.counter); | ||
4021 | 1011 | +# } | ||
4022 | 1012 | +} | ||
4023 | 1013 | + | ||
4024 | 1014 | + | ||
4025 | 1015 | +#-----------------------------------------Update Status stuff -------------------------- | ||
4026 | 1016 | +# | ||
4027 | 1017 | +# The update_status_callback is what we can use to pass plymouth whatever we want so | ||
4028 | 1018 | +# as to make use of features which are available only in this program (as opposed to | ||
4029 | 1019 | +# being available for any theme for the script plugin). | ||
4030 | 1020 | +# | ||
4031 | 1021 | +# Example: | ||
4032 | 1022 | +# | ||
4033 | 1023 | +# Thanks to the current implementation, some scripts can call "plymouth --update=fsck:sda1:40" | ||
4034 | 1024 | +# and this program will know that 1) we're performing and fsck check, 2) we're checking sda1, | ||
4035 | 1025 | +# 3) the program should set the label progress to 40% | ||
4036 | 1026 | +# | ||
4037 | 1027 | +# Other features can be easily added by parsing the string that we pass plymouth with "--update" | ||
4038 | 1028 | +# | ||
4039 | 1029 | +fun update_status_callback (status) { | ||
4040 | 1030 | +# Debug(status); | ||
4041 | 1031 | + if (!status) return; | ||
4042 | 1032 | + | ||
4043 | 1033 | + string_it = 0; | ||
4044 | 1034 | + update_strings[string_it] = ""; | ||
4045 | 1035 | + | ||
4046 | 1036 | + for (i=0; (String(status).CharAt(i) != ""); i++) { | ||
4047 | 1037 | + local.temp_char = String(status).CharAt(i); | ||
4048 | 1038 | + if (temp_char != ":") | ||
4049 | 1039 | + update_strings[string_it] += temp_char; | ||
4050 | 1040 | + else | ||
4051 | 1041 | + update_strings[++string_it] = ""; | ||
4052 | 1042 | + } | ||
4053 | 1043 | + | ||
4054 | 1044 | +# my_string = update_strings[0] + " " + update_strings[1] + " " + update_strings[2]; | ||
4055 | 1045 | +# Debug(my_string); | ||
4056 | 1046 | + # Let's assume that we're dealing with these strings fsck:sda1:40 | ||
4057 | 1047 | + if ((string_it >= 2) && (update_strings[0] == "fsck")) { | ||
4058 | 1048 | + | ||
4059 | 1049 | + device = update_strings[1]; | ||
4060 | 1050 | + progress = update_strings[2]; | ||
4061 | 1051 | + status_string[0] = update_strings[3]; # "Checking disk %1$d of %2$d (%3$d %% complete)" | ||
4062 | 1052 | + if (!status_string[0]) | ||
4063 | 1053 | + status_string[0] = "Checking disk %1$d of %2$d (%3$d %% complete)"; | ||
4064 | 1054 | + | ||
4065 | 1055 | + if ((device != "") && (progress != "")) { | ||
4066 | 1056 | + progress = StringToInteger (progress); | ||
4067 | 1057 | + | ||
4068 | 1058 | + # Make sure that the fsck_queue is initialised | ||
4069 | 1059 | + if (!global.fsck_queue) | ||
4070 | 1060 | + init_queue (); | ||
4071 | 1061 | + | ||
4072 | 1062 | + # Make sure that the fsck counter is initialised | ||
4073 | 1063 | + if (!global.counter) | ||
4074 | 1064 | + init_fsck_count (); | ||
4075 | 1065 | + | ||
4076 | 1066 | +# if (!global.progress_bar.extra_label.sprite) | ||
4077 | 1067 | +# create_extra_fsck_label (); | ||
4078 | 1068 | + | ||
4079 | 1069 | + # Keep track of the fsck check | ||
4080 | 1070 | + fsck_check (device, progress, status_string); | ||
4081 | 1071 | + } | ||
4082 | 1072 | + | ||
4083 | 1073 | + } | ||
4084 | 1074 | + | ||
4085 | 1075 | +} | ||
4086 | 1076 | +Plymouth.SetUpdateStatusFunction (update_status_callback); | ||
4087 | 1077 | + | ||
4088 | 1078 | +#-----------------------------------------Display Question stuff ----------------------- | ||
4089 | 1079 | + | ||
4090 | 1080 | +fun question_dialogue_setup (message_label, text_image) { | ||
4091 | 1081 | + #Debug("Question dialog setup"); | ||
4092 | 1082 | + | ||
4093 | 1083 | + local.field; | ||
4094 | 1084 | + local.content; | ||
4095 | 1085 | + local.margin; | ||
4096 | 1086 | + | ||
4097 | 1087 | + field.image = LoadScaleImage (question_field_filename); | ||
4098 | 1088 | + content = Sprite (); | ||
4099 | 1089 | + bullet_image = LoadScaleImage (progress_dot_off_filename); | ||
4100 | 1090 | + margin = bullet_image.GetWidth() / 2; | ||
4101 | 1091 | + | ||
4102 | 1092 | + # Hide the normal labels | ||
4103 | 1093 | + prompt_active = 1; | ||
4104 | 1094 | + if (message_notification[1].sprite) hide_message (1); | ||
4105 | 1095 | + | ||
4106 | 1096 | + # Set the prompt label | ||
4107 | 1097 | + label = get_message_label(message_label, 0, 1); | ||
4108 | 1098 | + label.z = 10000; | ||
4109 | 1099 | + | ||
4110 | 1100 | + setup_message (message_label, label.x, label.y, label.z, 2); | ||
4111 | 1101 | + show_message (2); | ||
4112 | 1102 | + | ||
4113 | 1103 | + # Set up the text field which contains the contents | ||
4114 | 1104 | + field.sprite = Sprite (); | ||
4115 | 1105 | + field.sprite.SetImage (field.image); | ||
4116 | 1106 | + | ||
4117 | 1107 | + # Centre the box horizontally | ||
4118 | 1108 | + field.x = Window.GetX () + Window.GetWidth () / 2 - field.image.GetWidth () / 2; | ||
4119 | 1109 | + content_x = field.x + margin; | ||
4120 | 1110 | + | ||
4121 | 1111 | + # Put the field below the second label. | ||
4122 | 1112 | + field.y = message_notification[2].y + label.height; | ||
4123 | 1113 | + content_y = field.y + field.image.GetHeight () / 2 - text_image.GetHeight () / 2; | ||
4124 | 1114 | + | ||
4125 | 1115 | + #Debug ("field x = " + field.x + ", y = " + field.y); | ||
4126 | 1116 | + field.z = 10000; | ||
4127 | 1117 | + field.sprite.SetX (field.x); | ||
4128 | 1118 | + field.sprite.SetY (field.y); | ||
4129 | 1119 | + field.sprite.SetZ (field.z); | ||
4130 | 1120 | + | ||
4131 | 1121 | + #Debug ("content_x = " + content_x + " content_y = " + content_y); | ||
4132 | 1122 | + content_z = field.z + 1; | ||
4133 | 1123 | + content.SetPosition (content_x, content_y, content_z); | ||
4134 | 1124 | + | ||
4135 | 1125 | + global.question_dialogue = local; | ||
4136 | 1126 | +} | ||
4137 | 1127 | + | ||
4138 | 1128 | +# The callback function is called when the display should display a question dialogue. | ||
4139 | 1129 | +# First arg is prompt string, the second is the field contents. | ||
4140 | 1130 | +fun display_question_callback (prompt, contents) { | ||
4141 | 1131 | + global.status = "question"; | ||
4142 | 1132 | + #Debug ("Reply: " + contents); | ||
4143 | 1133 | + | ||
4144 | 1134 | + textImage = ImageToText(contents); | ||
4145 | 1135 | + if (!global.question_dialogue) { | ||
4146 | 1136 | + question_dialogue_setup(prompt, textImage); | ||
4147 | 1137 | + } | ||
4148 | 1138 | + | ||
4149 | 1139 | + margin = global.question_dialogue.margin; | ||
4150 | 1140 | + fieldWidth = global.question_dialogue.field.image.GetWidth (); | ||
4151 | 1141 | + for (i = 0; ( (textImage.GetWidth () + 2 * margin ) > fieldWidth ); i++) { | ||
4152 | 1142 | + textImage = ImageToText(StringCopy (contents, i, StringLength (contents))); | ||
4153 | 1143 | + } | ||
4154 | 1144 | + | ||
4155 | 1145 | + global.question_dialogue.content.SetImage (textImage); | ||
4156 | 1146 | +} | ||
4157 | 1147 | + | ||
4158 | 1148 | + | ||
4159 | 1149 | +Plymouth.SetDisplayQuestionFunction (display_question_callback); | ||
4160 | 1150 | + | ||
4161 | 1151 | +#-----------------------------------------Refresh stuff -------------------------------- | ||
4162 | 1152 | +# | ||
4163 | 1153 | +# Calling Plymouth.SetRefreshFunction with a function will set that function to be | ||
4164 | 1154 | +# called up to 50 times every second, e.g. | ||
4165 | 1155 | +# | ||
4166 | 1156 | +# NOTE: if a refresh function is not set, Plymouth doesn't seem to be able to update | ||
4167 | 1157 | +# the screen correctly | ||
4168 | 1158 | +# | ||
4169 | 1159 | +fun refresh_callback () | ||
4170 | 1160 | +{ | ||
4171 | 1161 | + draw_logo (); | ||
4172 | 1162 | +} | ||
4173 | 1163 | +Plymouth.SetRefreshFunction (refresh_callback); | ||
4174 | 1164 | + | ||
4175 | 1165 | + | ||
4176 | 1166 | +#-----------------------------------------Display Normal stuff ----------------------- | ||
4177 | 1167 | +# | ||
4178 | 1168 | +# The callback function is called when the display should return to normal | ||
4179 | 1169 | +fun display_normal_callback () | ||
4180 | 1170 | +{ | ||
4181 | 1171 | + global.status = "normal"; | ||
4182 | 1172 | + if (global.password_dialogue) { | ||
4183 | 1173 | + password_dialogue_opacity (0); | ||
4184 | 1174 | + global.password_dialogue = NULL; | ||
4185 | 1175 | + if (message_notification[2].sprite) hide_message(2); | ||
4186 | 1176 | + prompt_active = 0; | ||
4187 | 1177 | + } | ||
4188 | 1178 | + if (global.question_dialogue) { | ||
4189 | 1179 | + question_dialogue_opacity (0); | ||
4190 | 1180 | + global.question_dialogue = NULL; | ||
4191 | 1181 | + if (message_notification[2].sprite) hide_message(2); | ||
4192 | 1182 | + prompt_active = 0; | ||
4193 | 1183 | + } | ||
4194 | 1184 | + | ||
4195 | 1185 | + if (message_notification[1].sprite) show_message (1); | ||
4196 | 1186 | + | ||
4197 | 1187 | +} | ||
4198 | 1188 | + | ||
4199 | 1189 | +Plymouth.SetDisplayNormalFunction (display_normal_callback); | ||
4200 | 1190 | + | ||
4201 | 1191 | + | ||
4202 | 1192 | +#----------------------------------------- Quit -------------------------------- | ||
4203 | 1193 | + | ||
4204 | 1194 | +# TODO: Maybe we should also hide any other dialog | ||
4205 | 1195 | +# Show the logo and make the progress indicator look full when on exit | ||
4206 | 1196 | +fun quit_callback () | ||
4207 | 1197 | +{ | ||
4208 | 1198 | + logo.sprite.SetOpacity (1); | ||
4209 | 1199 | + switch_on_bullets (); | ||
4210 | 1200 | +} | ||
4211 | 1201 | + | ||
4212 | 1202 | +Plymouth.SetQuitFunction(quit_callback); | ||
4213 | 0 | 1203 | ||
4214 | === added file 'debian/patches/use-upstart-private-socket.patch' | |||
4215 | --- debian/patches/use-upstart-private-socket.patch 1970-01-01 00:00:00 +0000 | |||
4216 | +++ debian/patches/use-upstart-private-socket.patch 2014-03-14 10:43:52 +0000 | |||
4217 | @@ -0,0 +1,198 @@ | |||
4218 | 1 | Description: use private upstart socket to start earlier | ||
4219 | 2 | Author: Dimitri John Ledkov <xnox@ubuntu.com> | ||
4220 | 3 | |||
4221 | 4 | --- a/src/upstart-bridge/ply-upstart-monitor.c | ||
4222 | 5 | +++ b/src/upstart-bridge/ply-upstart-monitor.c | ||
4223 | 6 | @@ -46,7 +46,6 @@ | ||
4224 | 7 | struct _ply_upstart_monitor | ||
4225 | 8 | { | ||
4226 | 9 | DBusConnection *connection; | ||
4227 | 10 | - char *owner; | ||
4228 | 11 | ply_event_loop_t *loop; | ||
4229 | 12 | ply_hashtable_t *jobs; | ||
4230 | 13 | ply_hashtable_t *all_instances; | ||
4231 | 14 | @@ -74,7 +73,8 @@ | ||
4232 | 15 | uint32_t call_failed : 1; | ||
4233 | 16 | } ply_upstart_monitor_instance_t; | ||
4234 | 17 | |||
4235 | 18 | -#define UPSTART_SERVICE "com.ubuntu.Upstart" | ||
4236 | 19 | +#define UPSTART_SERVICE NULL | ||
4237 | 20 | +#define DBUS_ADDRESS_UPSTART "unix:abstract=/com/ubuntu/upstart" | ||
4238 | 21 | #define UPSTART_PATH "/com/ubuntu/Upstart" | ||
4239 | 22 | #define UPSTART_INTERFACE_0_6 "com.ubuntu.Upstart0_6" | ||
4240 | 23 | #define UPSTART_INTERFACE_0_6_JOB "com.ubuntu.Upstart0_6.Job" | ||
4241 | 24 | @@ -579,82 +579,6 @@ | ||
4242 | 25 | dbus_message_unref (reply); | ||
4243 | 26 | } | ||
4244 | 27 | |||
4245 | 28 | -static void | ||
4246 | 29 | -on_get_name_owner_finished (DBusPendingCall *call, | ||
4247 | 30 | - ply_upstart_monitor_t *monitor) | ||
4248 | 31 | -{ | ||
4249 | 32 | - DBusMessage *reply, *message; | ||
4250 | 33 | - DBusError error; | ||
4251 | 34 | - const char *owner; | ||
4252 | 35 | - | ||
4253 | 36 | - assert (call != NULL); | ||
4254 | 37 | - assert (monitor != NULL); | ||
4255 | 38 | - | ||
4256 | 39 | - reply = dbus_pending_call_steal_reply (call); | ||
4257 | 40 | - if (reply == NULL) | ||
4258 | 41 | - return; | ||
4259 | 42 | - if (dbus_message_get_type (reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN) | ||
4260 | 43 | - goto out; | ||
4261 | 44 | - | ||
4262 | 45 | - dbus_error_init (&error); | ||
4263 | 46 | - dbus_message_get_args (reply, &error, | ||
4264 | 47 | - DBUS_TYPE_STRING, &owner, | ||
4265 | 48 | - DBUS_TYPE_INVALID); | ||
4266 | 49 | - if (dbus_error_is_set (&error)) | ||
4267 | 50 | - goto out; | ||
4268 | 51 | - dbus_error_free (&error); | ||
4269 | 52 | - | ||
4270 | 53 | - ply_trace ("owner = '%s'", owner); | ||
4271 | 54 | - | ||
4272 | 55 | - free (monitor->owner); | ||
4273 | 56 | - monitor->owner = strdup (owner); | ||
4274 | 57 | - | ||
4275 | 58 | - ply_trace ("calling GetAllJobs"); | ||
4276 | 59 | - message = dbus_message_new_method_call (UPSTART_SERVICE, UPSTART_PATH, | ||
4277 | 60 | - UPSTART_INTERFACE_0_6, | ||
4278 | 61 | - "GetAllJobs"); | ||
4279 | 62 | - dbus_connection_send_with_reply (monitor->connection, message, &call, -1); | ||
4280 | 63 | - dbus_message_unref (message); | ||
4281 | 64 | - if (call != NULL) | ||
4282 | 65 | - dbus_pending_call_set_notify (call, | ||
4283 | 66 | - (DBusPendingCallNotifyFunction) | ||
4284 | 67 | - on_get_all_jobs_finished, | ||
4285 | 68 | - monitor, NULL); | ||
4286 | 69 | - | ||
4287 | 70 | -out: | ||
4288 | 71 | - dbus_message_unref (reply); | ||
4289 | 72 | -} | ||
4290 | 73 | - | ||
4291 | 74 | -static DBusHandlerResult | ||
4292 | 75 | -name_owner_changed_handler (DBusConnection *connection, | ||
4293 | 76 | - DBusMessage *message, | ||
4294 | 77 | - ply_upstart_monitor_t *monitor) | ||
4295 | 78 | -{ | ||
4296 | 79 | - DBusError error; | ||
4297 | 80 | - const char *name, *old_owner, *new_owner; | ||
4298 | 81 | - | ||
4299 | 82 | - assert (connection != NULL); | ||
4300 | 83 | - assert (message != NULL); | ||
4301 | 84 | - assert (monitor != NULL); | ||
4302 | 85 | - | ||
4303 | 86 | - dbus_error_init (&error); | ||
4304 | 87 | - if (dbus_message_get_args (message, &error, | ||
4305 | 88 | - DBUS_TYPE_STRING, &name, | ||
4306 | 89 | - DBUS_TYPE_STRING, &old_owner, | ||
4307 | 90 | - DBUS_TYPE_STRING, &new_owner, | ||
4308 | 91 | - DBUS_TYPE_INVALID) && | ||
4309 | 92 | - strcmp (name, UPSTART_SERVICE) == 0) | ||
4310 | 93 | - { | ||
4311 | 94 | - if (new_owner) | ||
4312 | 95 | - ply_trace ("owner changed from '%s' to '%s'", old_owner, new_owner); | ||
4313 | 96 | - else | ||
4314 | 97 | - ply_trace ("owner left bus"); | ||
4315 | 98 | - free (monitor->owner); | ||
4316 | 99 | - monitor->owner = new_owner ? strdup (new_owner) : NULL; | ||
4317 | 100 | - } | ||
4318 | 101 | - | ||
4319 | 102 | - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* let other handlers try */ | ||
4320 | 103 | -} | ||
4321 | 104 | |||
4322 | 105 | static DBusHandlerResult | ||
4323 | 106 | job_added_handler (DBusConnection *connection, | ||
4324 | 107 | @@ -856,12 +780,6 @@ | ||
4325 | 108 | if (path == NULL) | ||
4326 | 109 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
4327 | 110 | |||
4328 | 111 | - if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, | ||
4329 | 112 | - "NameOwnerChanged") && | ||
4330 | 113 | - dbus_message_has_path (message, DBUS_PATH_DBUS) && | ||
4331 | 114 | - dbus_message_has_sender (message, DBUS_SERVICE_DBUS)) | ||
4332 | 115 | - return name_owner_changed_handler (connection, message, monitor); | ||
4333 | 116 | - | ||
4334 | 117 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6, | ||
4335 | 118 | "JobAdded")) | ||
4336 | 119 | return job_added_handler (connection, message, monitor); | ||
4337 | 120 | @@ -899,9 +817,7 @@ | ||
4338 | 121 | DBusError error; | ||
4339 | 122 | DBusConnection *connection; | ||
4340 | 123 | ply_upstart_monitor_t *monitor; | ||
4341 | 124 | - char *rule; | ||
4342 | 125 | DBusMessage *message; | ||
4343 | 126 | - const char *monitor_service = UPSTART_SERVICE; | ||
4344 | 127 | DBusPendingCall *call; | ||
4345 | 128 | |||
4346 | 129 | dbus_error_init (&error); | ||
4347 | 130 | @@ -909,7 +825,7 @@ | ||
4348 | 131 | /* Get a connection to the system bus and set it up to listen for messages | ||
4349 | 132 | * from Upstart. | ||
4350 | 133 | */ | ||
4351 | 134 | - connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); | ||
4352 | 135 | + connection = dbus_connection_open (DBUS_ADDRESS_UPSTART, &error); | ||
4353 | 136 | if (connection == NULL) | ||
4354 | 137 | { | ||
4355 | 138 | ply_error ("unable to connect to system bus: %s", error.message); | ||
4356 | 139 | @@ -938,52 +854,17 @@ | ||
4357 | 140 | return NULL; | ||
4358 | 141 | } | ||
4359 | 142 | |||
4360 | 143 | - asprintf (&rule, "type='%s',sender='%s',path='%s'," | ||
4361 | 144 | - "interface='%s',member='%s',arg0='%s'", | ||
4362 | 145 | - "signal", DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, | ||
4363 | 146 | - DBUS_INTERFACE_DBUS, "NameOwnerChanged", UPSTART_SERVICE); | ||
4364 | 147 | - dbus_bus_add_match (connection, rule, &error); | ||
4365 | 148 | - free (rule); | ||
4366 | 149 | - if (dbus_error_is_set (&error)) | ||
4367 | 150 | - { | ||
4368 | 151 | - ply_error ("unable to add match rule to system bus connection: %s", | ||
4369 | 152 | - error.message); | ||
4370 | 153 | - ply_upstart_monitor_free (monitor); | ||
4371 | 154 | - dbus_error_free (&error); | ||
4372 | 155 | - return NULL; | ||
4373 | 156 | - } | ||
4374 | 157 | - | ||
4375 | 158 | - asprintf (&rule, "type='%s',sender='%s'", "signal", UPSTART_SERVICE); | ||
4376 | 159 | - dbus_bus_add_match (connection, rule, &error); | ||
4377 | 160 | - free (rule); | ||
4378 | 161 | - if (dbus_error_is_set (&error)) | ||
4379 | 162 | - { | ||
4380 | 163 | - ply_error ("unable to add match rule to system bus connection: %s", | ||
4381 | 164 | - error.message); | ||
4382 | 165 | - ply_upstart_monitor_free (monitor); | ||
4383 | 166 | - dbus_error_free (&error); | ||
4384 | 167 | - return NULL; | ||
4385 | 168 | - } | ||
4386 | 169 | - | ||
4387 | 170 | - /* Start the state machine going: find out the current owner of the | ||
4388 | 171 | - * well-known Upstart name. | ||
4389 | 172 | - * Ignore errors: the worst case is that we don't get any messages back | ||
4390 | 173 | - * and our state machine does nothing. | ||
4391 | 174 | - */ | ||
4392 | 175 | - ply_trace ("calling GetNameOwner"); | ||
4393 | 176 | - message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, | ||
4394 | 177 | - DBUS_INTERFACE_DBUS, "GetNameOwner"); | ||
4395 | 178 | - dbus_message_append_args (message, | ||
4396 | 179 | - DBUS_TYPE_STRING, &monitor_service, | ||
4397 | 180 | - DBUS_TYPE_INVALID); | ||
4398 | 181 | - dbus_connection_send_with_reply (connection, message, &call, -1); | ||
4399 | 182 | + ply_trace ("calling GetAllJobs"); | ||
4400 | 183 | + message = dbus_message_new_method_call (UPSTART_SERVICE, UPSTART_PATH, | ||
4401 | 184 | + UPSTART_INTERFACE_0_6, | ||
4402 | 185 | + "GetAllJobs"); | ||
4403 | 186 | + dbus_connection_send_with_reply (monitor->connection, message, &call, -1); | ||
4404 | 187 | dbus_message_unref (message); | ||
4405 | 188 | if (call != NULL) | ||
4406 | 189 | dbus_pending_call_set_notify (call, | ||
4407 | 190 | (DBusPendingCallNotifyFunction) | ||
4408 | 191 | - on_get_name_owner_finished, | ||
4409 | 192 | - monitor, | ||
4410 | 193 | - NULL); | ||
4411 | 194 | + on_get_all_jobs_finished, | ||
4412 | 195 | + monitor, NULL); | ||
4413 | 196 | |||
4414 | 197 | if (loop != NULL) | ||
4415 | 198 | ply_upstart_monitor_connect_to_event_loop (monitor, loop); | ||
4416 | 0 | 199 | ||
4417 | === modified file 'debian/plymouth-theme-ubuntu-logo.postinst' | |||
4418 | --- debian/plymouth-theme-ubuntu-logo.postinst 2011-04-15 13:35:04 +0000 | |||
4419 | +++ debian/plymouth-theme-ubuntu-logo.postinst 2014-03-14 10:43:52 +0000 | |||
4420 | @@ -24,6 +24,12 @@ | |||
4421 | 24 | --slave /lib/plymouth/themes/default.grub default.plymouth.grub \ | 24 | --slave /lib/plymouth/themes/default.grub default.plymouth.grub \ |
4422 | 25 | /lib/plymouth/themes/ubuntu-logo/ubuntu-logo.grub | 25 | /lib/plymouth/themes/ubuntu-logo/ubuntu-logo.grub |
4423 | 26 | 26 | ||
4424 | 27 | update-alternatives \ | ||
4425 | 28 | --install /lib/plymouth/themes/default.plymouth default.plymouth \ | ||
4426 | 29 | /lib/plymouth/themes/ubuntu-logo/ubuntu-logo-scale-2.plymouth 99 \ | ||
4427 | 30 | --slave /lib/plymouth/themes/default.grub default.plymouth.grub \ | ||
4428 | 31 | /lib/plymouth/themes/ubuntu-logo/ubuntu-logo.grub | ||
4429 | 32 | |||
4430 | 27 | if which update-initramfs >/dev/null 2>&1 | 33 | if which update-initramfs >/dev/null 2>&1 |
4431 | 28 | then | 34 | then |
4432 | 29 | update-initramfs -u | 35 | update-initramfs -u |
4433 | 30 | 36 | ||
4434 | === modified file 'debian/plymouth-theme-ubuntu-logo.prerm' | |||
4435 | --- debian/plymouth-theme-ubuntu-logo.prerm 2011-02-09 20:41:53 +0000 | |||
4436 | +++ debian/plymouth-theme-ubuntu-logo.prerm 2014-03-14 10:43:52 +0000 | |||
4437 | @@ -5,6 +5,8 @@ | |||
4438 | 5 | if [ "x$1" = xremove ]; then | 5 | if [ "x$1" = xremove ]; then |
4439 | 6 | update-alternatives \ | 6 | update-alternatives \ |
4440 | 7 | --remove default.plymouth /lib/plymouth/themes/ubuntu-logo/ubuntu-logo.plymouth | 7 | --remove default.plymouth /lib/plymouth/themes/ubuntu-logo/ubuntu-logo.plymouth |
4441 | 8 | update-alternatives \ | ||
4442 | 9 | --remove default.plymouth /lib/plymouth/themes/ubuntu-logo/ubuntu-logo-scale-2.plymouth | ||
4443 | 8 | fi | 10 | fi |
4444 | 9 | 11 | ||
4445 | 10 | #DEBHELPER# | 12 | #DEBHELPER# |
4446 | 11 | 13 | ||
4447 | === modified file 'debian/plymouth.plymouth-upstart-bridge.upstart' | |||
4448 | --- debian/plymouth.plymouth-upstart-bridge.upstart 2012-09-07 18:03:39 +0000 | |||
4449 | +++ debian/plymouth.plymouth-upstart-bridge.upstart 2014-03-14 10:43:52 +0000 | |||
4450 | @@ -5,9 +5,12 @@ | |||
4451 | 5 | 5 | ||
4452 | 6 | description "bridge from Upstart state changes to Plymouth" | 6 | description "bridge from Upstart state changes to Plymouth" |
4453 | 7 | 7 | ||
4455 | 8 | start on (started dbus | 8 | respawn |
4456 | 9 | |||
4457 | 10 | start on (startup | ||
4458 | 9 | or runlevel [06]) | 11 | or runlevel [06]) |
4460 | 10 | stop on stopping plymouth | 12 | stop on (stopping plymouth |
4461 | 13 | or stopping plymouth-shutdown) | ||
4462 | 11 | 14 | ||
4463 | 12 | console output | 15 | console output |
4464 | 13 | 16 | ||
4465 | 14 | 17 | ||
4466 | === modified file 'src/upstart-bridge/ply-upstart-monitor.c' | |||
4467 | --- src/upstart-bridge/ply-upstart-monitor.c 2011-03-12 22:54:53 +0000 | |||
4468 | +++ src/upstart-bridge/ply-upstart-monitor.c 2014-03-14 10:43:52 +0000 | |||
4469 | @@ -46,7 +46,6 @@ | |||
4470 | 46 | struct _ply_upstart_monitor | 46 | struct _ply_upstart_monitor |
4471 | 47 | { | 47 | { |
4472 | 48 | DBusConnection *connection; | 48 | DBusConnection *connection; |
4473 | 49 | char *owner; | ||
4474 | 50 | ply_event_loop_t *loop; | 49 | ply_event_loop_t *loop; |
4475 | 51 | ply_hashtable_t *jobs; | 50 | ply_hashtable_t *jobs; |
4476 | 52 | ply_hashtable_t *all_instances; | 51 | ply_hashtable_t *all_instances; |
4477 | @@ -74,7 +73,8 @@ | |||
4478 | 74 | uint32_t call_failed : 1; | 73 | uint32_t call_failed : 1; |
4479 | 75 | } ply_upstart_monitor_instance_t; | 74 | } ply_upstart_monitor_instance_t; |
4480 | 76 | 75 | ||
4482 | 77 | #define UPSTART_SERVICE "com.ubuntu.Upstart" | 76 | #define UPSTART_SERVICE NULL |
4483 | 77 | #define DBUS_ADDRESS_UPSTART "unix:abstract=/com/ubuntu/upstart" | ||
4484 | 78 | #define UPSTART_PATH "/com/ubuntu/Upstart" | 78 | #define UPSTART_PATH "/com/ubuntu/Upstart" |
4485 | 79 | #define UPSTART_INTERFACE_0_6 "com.ubuntu.Upstart0_6" | 79 | #define UPSTART_INTERFACE_0_6 "com.ubuntu.Upstart0_6" |
4486 | 80 | #define UPSTART_INTERFACE_0_6_JOB "com.ubuntu.Upstart0_6.Job" | 80 | #define UPSTART_INTERFACE_0_6_JOB "com.ubuntu.Upstart0_6.Job" |
4487 | @@ -273,7 +273,7 @@ | |||
4488 | 273 | DBUS_TYPE_STRING) | 273 | DBUS_TYPE_STRING) |
4489 | 274 | goto next_item; | 274 | goto next_item; |
4490 | 275 | dbus_message_iter_get_basic (&variant_iter, &description); | 275 | dbus_message_iter_get_basic (&variant_iter, &description); |
4492 | 276 | if (description != NULL) | 276 | if (description != NULL && description[0]) |
4493 | 277 | { | 277 | { |
4494 | 278 | ply_trace ("description = '%s'", description); | 278 | ply_trace ("description = '%s'", description); |
4495 | 279 | job->properties.description = strdup (description); | 279 | job->properties.description = strdup (description); |
4496 | @@ -579,82 +579,6 @@ | |||
4497 | 579 | dbus_message_unref (reply); | 579 | dbus_message_unref (reply); |
4498 | 580 | } | 580 | } |
4499 | 581 | 581 | ||
4500 | 582 | static void | ||
4501 | 583 | on_get_name_owner_finished (DBusPendingCall *call, | ||
4502 | 584 | ply_upstart_monitor_t *monitor) | ||
4503 | 585 | { | ||
4504 | 586 | DBusMessage *reply, *message; | ||
4505 | 587 | DBusError error; | ||
4506 | 588 | const char *owner; | ||
4507 | 589 | |||
4508 | 590 | assert (call != NULL); | ||
4509 | 591 | assert (monitor != NULL); | ||
4510 | 592 | |||
4511 | 593 | reply = dbus_pending_call_steal_reply (call); | ||
4512 | 594 | if (reply == NULL) | ||
4513 | 595 | return; | ||
4514 | 596 | if (dbus_message_get_type (reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN) | ||
4515 | 597 | goto out; | ||
4516 | 598 | |||
4517 | 599 | dbus_error_init (&error); | ||
4518 | 600 | dbus_message_get_args (reply, &error, | ||
4519 | 601 | DBUS_TYPE_STRING, &owner, | ||
4520 | 602 | DBUS_TYPE_INVALID); | ||
4521 | 603 | if (dbus_error_is_set (&error)) | ||
4522 | 604 | goto out; | ||
4523 | 605 | dbus_error_free (&error); | ||
4524 | 606 | |||
4525 | 607 | ply_trace ("owner = '%s'", owner); | ||
4526 | 608 | |||
4527 | 609 | free (monitor->owner); | ||
4528 | 610 | monitor->owner = strdup (owner); | ||
4529 | 611 | |||
4530 | 612 | ply_trace ("calling GetAllJobs"); | ||
4531 | 613 | message = dbus_message_new_method_call (UPSTART_SERVICE, UPSTART_PATH, | ||
4532 | 614 | UPSTART_INTERFACE_0_6, | ||
4533 | 615 | "GetAllJobs"); | ||
4534 | 616 | dbus_connection_send_with_reply (monitor->connection, message, &call, -1); | ||
4535 | 617 | dbus_message_unref (message); | ||
4536 | 618 | if (call != NULL) | ||
4537 | 619 | dbus_pending_call_set_notify (call, | ||
4538 | 620 | (DBusPendingCallNotifyFunction) | ||
4539 | 621 | on_get_all_jobs_finished, | ||
4540 | 622 | monitor, NULL); | ||
4541 | 623 | |||
4542 | 624 | out: | ||
4543 | 625 | dbus_message_unref (reply); | ||
4544 | 626 | } | ||
4545 | 627 | |||
4546 | 628 | static DBusHandlerResult | ||
4547 | 629 | name_owner_changed_handler (DBusConnection *connection, | ||
4548 | 630 | DBusMessage *message, | ||
4549 | 631 | ply_upstart_monitor_t *monitor) | ||
4550 | 632 | { | ||
4551 | 633 | DBusError error; | ||
4552 | 634 | const char *name, *old_owner, *new_owner; | ||
4553 | 635 | |||
4554 | 636 | assert (connection != NULL); | ||
4555 | 637 | assert (message != NULL); | ||
4556 | 638 | assert (monitor != NULL); | ||
4557 | 639 | |||
4558 | 640 | dbus_error_init (&error); | ||
4559 | 641 | if (dbus_message_get_args (message, &error, | ||
4560 | 642 | DBUS_TYPE_STRING, &name, | ||
4561 | 643 | DBUS_TYPE_STRING, &old_owner, | ||
4562 | 644 | DBUS_TYPE_STRING, &new_owner, | ||
4563 | 645 | DBUS_TYPE_INVALID) && | ||
4564 | 646 | strcmp (name, UPSTART_SERVICE) == 0) | ||
4565 | 647 | { | ||
4566 | 648 | if (new_owner) | ||
4567 | 649 | ply_trace ("owner changed from '%s' to '%s'", old_owner, new_owner); | ||
4568 | 650 | else | ||
4569 | 651 | ply_trace ("owner left bus"); | ||
4570 | 652 | free (monitor->owner); | ||
4571 | 653 | monitor->owner = new_owner ? strdup (new_owner) : NULL; | ||
4572 | 654 | } | ||
4573 | 655 | |||
4574 | 656 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* let other handlers try */ | ||
4575 | 657 | } | ||
4576 | 658 | 582 | ||
4577 | 659 | static DBusHandlerResult | 583 | static DBusHandlerResult |
4578 | 660 | job_added_handler (DBusConnection *connection, | 584 | job_added_handler (DBusConnection *connection, |
4579 | @@ -856,12 +780,6 @@ | |||
4580 | 856 | if (path == NULL) | 780 | if (path == NULL) |
4581 | 857 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 781 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
4582 | 858 | 782 | ||
4583 | 859 | if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, | ||
4584 | 860 | "NameOwnerChanged") && | ||
4585 | 861 | dbus_message_has_path (message, DBUS_PATH_DBUS) && | ||
4586 | 862 | dbus_message_has_sender (message, DBUS_SERVICE_DBUS)) | ||
4587 | 863 | return name_owner_changed_handler (connection, message, monitor); | ||
4588 | 864 | |||
4589 | 865 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6, | 783 | if (dbus_message_is_signal (message, UPSTART_INTERFACE_0_6, |
4590 | 866 | "JobAdded")) | 784 | "JobAdded")) |
4591 | 867 | return job_added_handler (connection, message, monitor); | 785 | return job_added_handler (connection, message, monitor); |
4592 | @@ -899,9 +817,7 @@ | |||
4593 | 899 | DBusError error; | 817 | DBusError error; |
4594 | 900 | DBusConnection *connection; | 818 | DBusConnection *connection; |
4595 | 901 | ply_upstart_monitor_t *monitor; | 819 | ply_upstart_monitor_t *monitor; |
4596 | 902 | char *rule; | ||
4597 | 903 | DBusMessage *message; | 820 | DBusMessage *message; |
4598 | 904 | const char *monitor_service = UPSTART_SERVICE; | ||
4599 | 905 | DBusPendingCall *call; | 821 | DBusPendingCall *call; |
4600 | 906 | 822 | ||
4601 | 907 | dbus_error_init (&error); | 823 | dbus_error_init (&error); |
4602 | @@ -909,7 +825,7 @@ | |||
4603 | 909 | /* Get a connection to the system bus and set it up to listen for messages | 825 | /* Get a connection to the system bus and set it up to listen for messages |
4604 | 910 | * from Upstart. | 826 | * from Upstart. |
4605 | 911 | */ | 827 | */ |
4607 | 912 | connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); | 828 | connection = dbus_connection_open (DBUS_ADDRESS_UPSTART, &error); |
4608 | 913 | if (connection == NULL) | 829 | if (connection == NULL) |
4609 | 914 | { | 830 | { |
4610 | 915 | ply_error ("unable to connect to system bus: %s", error.message); | 831 | ply_error ("unable to connect to system bus: %s", error.message); |
4611 | @@ -938,52 +854,17 @@ | |||
4612 | 938 | return NULL; | 854 | return NULL; |
4613 | 939 | } | 855 | } |
4614 | 940 | 856 | ||
4654 | 941 | asprintf (&rule, "type='%s',sender='%s',path='%s'," | 857 | ply_trace ("calling GetAllJobs"); |
4655 | 942 | "interface='%s',member='%s',arg0='%s'", | 858 | message = dbus_message_new_method_call (UPSTART_SERVICE, UPSTART_PATH, |
4656 | 943 | "signal", DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, | 859 | UPSTART_INTERFACE_0_6, |
4657 | 944 | DBUS_INTERFACE_DBUS, "NameOwnerChanged", UPSTART_SERVICE); | 860 | "GetAllJobs"); |
4658 | 945 | dbus_bus_add_match (connection, rule, &error); | 861 | dbus_connection_send_with_reply (monitor->connection, message, &call, -1); |
4620 | 946 | free (rule); | ||
4621 | 947 | if (dbus_error_is_set (&error)) | ||
4622 | 948 | { | ||
4623 | 949 | ply_error ("unable to add match rule to system bus connection: %s", | ||
4624 | 950 | error.message); | ||
4625 | 951 | ply_upstart_monitor_free (monitor); | ||
4626 | 952 | dbus_error_free (&error); | ||
4627 | 953 | return NULL; | ||
4628 | 954 | } | ||
4629 | 955 | |||
4630 | 956 | asprintf (&rule, "type='%s',sender='%s'", "signal", UPSTART_SERVICE); | ||
4631 | 957 | dbus_bus_add_match (connection, rule, &error); | ||
4632 | 958 | free (rule); | ||
4633 | 959 | if (dbus_error_is_set (&error)) | ||
4634 | 960 | { | ||
4635 | 961 | ply_error ("unable to add match rule to system bus connection: %s", | ||
4636 | 962 | error.message); | ||
4637 | 963 | ply_upstart_monitor_free (monitor); | ||
4638 | 964 | dbus_error_free (&error); | ||
4639 | 965 | return NULL; | ||
4640 | 966 | } | ||
4641 | 967 | |||
4642 | 968 | /* Start the state machine going: find out the current owner of the | ||
4643 | 969 | * well-known Upstart name. | ||
4644 | 970 | * Ignore errors: the worst case is that we don't get any messages back | ||
4645 | 971 | * and our state machine does nothing. | ||
4646 | 972 | */ | ||
4647 | 973 | ply_trace ("calling GetNameOwner"); | ||
4648 | 974 | message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, | ||
4649 | 975 | DBUS_INTERFACE_DBUS, "GetNameOwner"); | ||
4650 | 976 | dbus_message_append_args (message, | ||
4651 | 977 | DBUS_TYPE_STRING, &monitor_service, | ||
4652 | 978 | DBUS_TYPE_INVALID); | ||
4653 | 979 | dbus_connection_send_with_reply (connection, message, &call, -1); | ||
4659 | 980 | dbus_message_unref (message); | 862 | dbus_message_unref (message); |
4660 | 981 | if (call != NULL) | 863 | if (call != NULL) |
4661 | 982 | dbus_pending_call_set_notify (call, | 864 | dbus_pending_call_set_notify (call, |
4662 | 983 | (DBusPendingCallNotifyFunction) | 865 | (DBusPendingCallNotifyFunction) |
4666 | 984 | on_get_name_owner_finished, | 866 | on_get_all_jobs_finished, |
4667 | 985 | monitor, | 867 | monitor, NULL); |
4665 | 986 | NULL); | ||
4668 | 987 | 868 | ||
4669 | 988 | if (loop != NULL) | 869 | if (loop != NULL) |
4670 | 989 | ply_upstart_monitor_connect_to_event_loop (monitor, loop); | 870 | ply_upstart_monitor_connect_to_event_loop (monitor, loop); |
4671 | 990 | 871 | ||
4672 | === modified file 'src/upstart-bridge/plymouth-upstart-bridge.c' | |||
4673 | --- src/upstart-bridge/plymouth-upstart-bridge.c 2011-03-12 22:54:53 +0000 | |||
4674 | +++ src/upstart-bridge/plymouth-upstart-bridge.c 2014-03-14 10:43:52 +0000 | |||
4675 | @@ -307,7 +307,9 @@ | |||
4676 | 307 | if (should_be_verbose && !ply_is_tracing ()) | 307 | if (should_be_verbose && !ply_is_tracing ()) |
4677 | 308 | ply_toggle_tracing (); | 308 | ply_toggle_tracing (); |
4678 | 309 | 309 | ||
4680 | 310 | setupterm (NULL, STDOUT_FILENO, NULL); | 310 | /* Don't bail on dummy/hardcopy terminals */ |
4681 | 311 | int errret=0; | ||
4682 | 312 | setupterm (NULL, STDOUT_FILENO, &errret); | ||
4683 | 311 | 313 | ||
4684 | 312 | is_connected = ply_boot_client_connect (state.client, | 314 | is_connected = ply_boot_client_connect (state.client, |
4685 | 313 | (ply_boot_client_disconnect_handler_t) | 315 | (ply_boot_client_disconnect_handler_t) |
4686 | 314 | 316 | ||
4687 | === modified file 'themes/ubuntu-logo/Makefile.am' | |||
4688 | --- themes/ubuntu-logo/Makefile.am 2011-04-15 13:35:04 +0000 | |||
4689 | +++ themes/ubuntu-logo/Makefile.am 2014-03-14 10:43:52 +0000 | |||
4690 | @@ -1,6 +1,7 @@ | |||
4691 | 1 | themedir = $(datadir)/plymouth/themes/ubuntu-logo | 1 | themedir = $(datadir)/plymouth/themes/ubuntu-logo |
4693 | 2 | nodist_theme_DATA = ubuntu-logo.plymouth | 2 | nodist_theme_DATA = ubuntu-logo.plymouth ubuntu-logo-scale-2.plymouth |
4694 | 3 | dist_theme_DATA = ubuntu-logo.script \ | 3 | dist_theme_DATA = ubuntu-logo.script \ |
4695 | 4 | ubuntu-logo-scale-2.script \ | ||
4696 | 4 | ubuntu-logo.grub \ | 5 | ubuntu-logo.grub \ |
4697 | 5 | ubuntu_logo.png \ | 6 | ubuntu_logo.png \ |
4698 | 6 | ubuntu_logo16.png \ | 7 | ubuntu_logo16.png \ |
4699 | @@ -13,11 +14,23 @@ | |||
4700 | 13 | 14 | ||
4701 | 14 | 15 | ||
4702 | 15 | 16 | ||
4705 | 16 | MAINTAINERCLEANFILES = Makefile.in ubuntu-logo.plymouth | 17 | MAINTAINERCLEANFILES = Makefile.in ubuntu-logo.plymouth ubuntu-logo-scale-2.plymouth ubuntu-logo.script ubuntu-logo-scale-2.script |
4706 | 17 | CLEANFILES = ubuntu-logo.plymouth | 18 | CLEANFILES = ubuntu-logo.plymouth ubuntu-logo-scale-2.plymouth ubuntu-logo.script ubuntu-logo-scale-2.script |
4707 | 18 | 19 | ||
4708 | 19 | ubuntu-logo.plymouth: $(srcdir)/ubuntu-logo.plymouth.in | 20 | ubuntu-logo.plymouth: $(srcdir)/ubuntu-logo.plymouth.in |
4710 | 20 | sed -e 's,[@]PLYMOUTH_THEME_PATH[@],$(PLYMOUTH_THEME_PATH),g' \ | 21 | sed -e 's,[@]PLYMOUTH_THEME_PATH[@],$(PLYMOUTH_THEME_PATH),g;s,[@]EXTRA_NAME[@],,g;s,[@]SCRIPT_NAME[@],ubuntu-logo,g' \ |
4711 | 21 | $(srcdir)/ubuntu-logo.plymouth.in > ubuntu-logo.plymouth | 22 | $(srcdir)/ubuntu-logo.plymouth.in > ubuntu-logo.plymouth |
4712 | 22 | 23 | ||
4714 | 23 | EXTRA_DIST = ubuntu-logo.plymouth.in | 24 | ubuntu-logo-scale-2.plymouth: $(srcdir)/ubuntu-logo.plymouth.in |
4715 | 25 | sed -e 's,[@]PLYMOUTH_THEME_PATH[@],$(PLYMOUTH_THEME_PATH),g;s,[@]EXTRA_NAME[@],(Scale x2),g;s,[@]SCRIPT_NAME[@],ubuntu-logo-scale-2,g' \ | ||
4716 | 26 | $(srcdir)/ubuntu-logo.plymouth.in > ubuntu-logo-scale-2.plymouth | ||
4717 | 27 | |||
4718 | 28 | ubuntu-logo.script: $(srcdir)/ubuntu-logo.script.in | ||
4719 | 29 | sed -e 's,[@]SCALEFACTOR[@],1,g' \ | ||
4720 | 30 | $(srcdir)/ubuntu-logo.script.in > ubuntu-logo.script | ||
4721 | 31 | |||
4722 | 32 | ubuntu-logo-scale-2.script: $(srcdir)/ubuntu-logo.script.in | ||
4723 | 33 | sed -e 's,[@]SCALEFACTOR[@],2,g' \ | ||
4724 | 34 | $(srcdir)/ubuntu-logo.script.in > ubuntu-logo-scale-2.script | ||
4725 | 35 | |||
4726 | 36 | EXTRA_DIST = ubuntu-logo.plymouth.in ubuntu-logo.script.in | ||
4727 | 24 | 37 | ||
4728 | === modified file 'themes/ubuntu-logo/ubuntu-logo.plymouth.in' | |||
4729 | --- themes/ubuntu-logo/ubuntu-logo.plymouth.in 2009-12-07 19:55:24 +0000 | |||
4730 | +++ themes/ubuntu-logo/ubuntu-logo.plymouth.in 2014-03-14 10:43:52 +0000 | |||
4731 | @@ -1,8 +1,8 @@ | |||
4732 | 1 | [Plymouth Theme] | 1 | [Plymouth Theme] |
4734 | 2 | Name=Ubuntu Logo | 2 | Name=Ubuntu Logo @EXTRA_NAME@ |
4735 | 3 | Description=A theme that features a blank background with a logo. | 3 | Description=A theme that features a blank background with a logo. |
4736 | 4 | ModuleName=script | 4 | ModuleName=script |
4737 | 5 | 5 | ||
4738 | 6 | [script] | 6 | [script] |
4739 | 7 | ImageDir=@PLYMOUTH_THEME_PATH@/ubuntu-logo | 7 | ImageDir=@PLYMOUTH_THEME_PATH@/ubuntu-logo |
4741 | 8 | ScriptFile=@PLYMOUTH_THEME_PATH@/ubuntu-logo/ubuntu-logo.script | 8 | ScriptFile=@PLYMOUTH_THEME_PATH@/ubuntu-logo/@SCRIPT_NAME@.script |
4742 | 9 | 9 | ||
4743 | === renamed file 'themes/ubuntu-logo/ubuntu-logo.script' => 'themes/ubuntu-logo/ubuntu-logo.script.in' | |||
4744 | --- themes/ubuntu-logo/ubuntu-logo.script 2013-02-14 00:56:49 +0000 | |||
4745 | +++ themes/ubuntu-logo/ubuntu-logo.script.in 2014-03-14 10:43:52 +0000 | |||
4746 | @@ -46,12 +46,27 @@ | |||
4747 | 46 | debugsprite_bottom = Sprite(); | 46 | debugsprite_bottom = Sprite(); |
4748 | 47 | debugsprite_medium = Sprite(); | 47 | debugsprite_medium = Sprite(); |
4749 | 48 | 48 | ||
4750 | 49 | # Ubuntu Font | ||
4751 | 50 | ubuntufont = "Ubuntu 11"; | ||
4752 | 51 | ubuntualignment = "center"; | ||
4753 | 52 | |||
4754 | 53 | # Scale factor | ||
4755 | 54 | scalefactor = @SCALEFACTOR@; | ||
4756 | 55 | |||
4757 | 49 | # are we currently prompting for a password? | 56 | # are we currently prompting for a password? |
4758 | 50 | prompt_active = 0; | 57 | prompt_active = 0; |
4759 | 51 | 58 | ||
4760 | 59 | # Generic scalable image loader | ||
4761 | 60 | fun LoadScaleImage (imagepath) { | ||
4762 | 61 | image = Image (imagepath); | ||
4763 | 62 | image = image.Scale (image.GetWidth() * scalefactor, image.GetHeight() * scalefactor); | ||
4764 | 63 | return image; | ||
4765 | 64 | } | ||
4766 | 65 | |||
4767 | 52 | # General purpose function to create text | 66 | # General purpose function to create text |
4768 | 53 | fun WriteText (text, colour) { | 67 | fun WriteText (text, colour) { |
4770 | 54 | image = Image.Text (text, colour.red, colour.green, colour.blue); | 68 | image = Image.Text (text, colour.red, colour.green, colour.blue, color.alpha, ubuntufont, ubuntualignment); |
4771 | 69 | image = image.Scale (image.GetWidth() * scalefactor, image.GetHeight() * scalefactor); | ||
4772 | 55 | return image; | 70 | return image; |
4773 | 56 | } | 71 | } |
4774 | 57 | 72 | ||
4775 | @@ -184,7 +199,7 @@ | |||
4776 | 184 | question_field_filename = "password_field.png"; | 199 | question_field_filename = "password_field.png"; |
4777 | 185 | } | 200 | } |
4778 | 186 | 201 | ||
4780 | 187 | logo.image = Image (logo_filename); | 202 | logo.image = LoadScaleImage (logo_filename); |
4781 | 188 | logo.sprite = Sprite (); | 203 | logo.sprite = Sprite (); |
4782 | 189 | logo.sprite.SetImage (logo.image); | 204 | logo.sprite.SetImage (logo.image); |
4783 | 190 | logo.width = logo.image.GetWidth (); | 205 | logo.width = logo.image.GetWidth (); |
4784 | @@ -206,8 +221,8 @@ | |||
4785 | 206 | 221 | ||
4786 | 207 | status = "normal"; | 222 | status = "normal"; |
4787 | 208 | 223 | ||
4790 | 209 | progress_indicator.bullet_off = Image (progress_dot_off_filename); | 224 | progress_indicator.bullet_off = LoadScaleImage (progress_dot_off_filename); |
4791 | 210 | progress_indicator.bullet_on = Image (progress_dot_on_filename); | 225 | progress_indicator.bullet_on = LoadScaleImage (progress_dot_on_filename); |
4792 | 211 | progress_indicator.bullet_width = progress_indicator.bullet_off.GetWidth (); | 226 | progress_indicator.bullet_width = progress_indicator.bullet_off.GetWidth (); |
4793 | 212 | progress_indicator.bullet_height = progress_indicator.bullet_off.GetHeight (); | 227 | progress_indicator.bullet_height = progress_indicator.bullet_off.GetHeight (); |
4794 | 213 | progress_indicator.bullet_hspacing = progress_indicator.bullet_width * 1.1; | 228 | progress_indicator.bullet_hspacing = progress_indicator.bullet_width * 1.1; |
4795 | @@ -509,9 +524,8 @@ | |||
4796 | 509 | 524 | ||
4797 | 510 | local.entry; | 525 | local.entry; |
4798 | 511 | local.bullet_image; | 526 | local.bullet_image; |
4802 | 512 | 527 | bullet_image = LoadScaleImage (progress_dot_off_filename); | |
4803 | 513 | bullet_image = Image (progress_dot_off_filename); | 528 | entry.image = LoadScaleImage (password_field_filename); |
4801 | 514 | entry.image = Image (password_field_filename); | ||
4804 | 515 | 529 | ||
4805 | 516 | # Hide the normal labels | 530 | # Hide the normal labels |
4806 | 517 | prompt_active = 1; | 531 | prompt_active = 1; |
4807 | @@ -1010,9 +1024,9 @@ | |||
4808 | 1010 | local.content; | 1024 | local.content; |
4809 | 1011 | local.margin; | 1025 | local.margin; |
4810 | 1012 | 1026 | ||
4812 | 1013 | field.image = Image (question_field_filename); | 1027 | field.image = LoadScaleImage (question_field_filename); |
4813 | 1014 | content = Sprite (); | 1028 | content = Sprite (); |
4815 | 1015 | bullet_image = Image (progress_dot_off_filename); | 1029 | bullet_image = LoadScaleImage (progress_dot_off_filename); |
4816 | 1016 | margin = bullet_image.GetWidth() / 2; | 1030 | margin = bullet_image.GetWidth() / 2; |
4817 | 1017 | 1031 | ||
4818 | 1018 | # Hide the normal labels | 1032 | # Hide the normal labels |