diff options
author | LRN <lrn1986@gmail.com> | 2013-03-13 17:49:26 +0000 |
---|---|---|
committer | LRN <lrn1986@gmail.com> | 2013-03-13 17:49:26 +0000 |
commit | 405f776bc08486af4edb80e18149c0829732b347 (patch) | |
tree | d5fc635a51641dec6b53cb2540276f34ae8f6210 /src/arm/gnunet-arm.c | |
parent | 3ceae682287492ecc768aea5c4c463216a35774d (diff) | |
download | gnunet-405f776bc08486af4edb80e18149c0829732b347.tar.gz gnunet-405f776bc08486af4edb80e18149c0829732b347.zip |
All-encompassing ARM update
Diffstat (limited to 'src/arm/gnunet-arm.c')
-rw-r--r-- | src/arm/gnunet-arm.c | 521 |
1 files changed, 332 insertions, 189 deletions
diff --git a/src/arm/gnunet-arm.c b/src/arm/gnunet-arm.c index 8a98ba06b..9eb64e316 100644 --- a/src/arm/gnunet-arm.c +++ b/src/arm/gnunet-arm.c | |||
@@ -111,6 +111,11 @@ static int ret; | |||
111 | static struct GNUNET_ARM_Handle *h; | 111 | static struct GNUNET_ARM_Handle *h; |
112 | 112 | ||
113 | /** | 113 | /** |
114 | * Monitor connection with ARM. | ||
115 | */ | ||
116 | static struct GNUNET_ARM_MonitorHandle *m; | ||
117 | |||
118 | /** | ||
114 | * Our configuration. | 119 | * Our configuration. |
115 | */ | 120 | */ |
116 | static struct GNUNET_CONFIGURATION_Handle *cfg; | 121 | static struct GNUNET_CONFIGURATION_Handle *cfg; |
@@ -137,105 +142,6 @@ static unsigned int no_stderr; | |||
137 | 142 | ||
138 | 143 | ||
139 | /** | 144 | /** |
140 | * Main continuation-passing-style loop. Runs the various | ||
141 | * jobs that we've been asked to do in order. | ||
142 | * | ||
143 | * @param cls closure, unused | ||
144 | * @param tc context, unused | ||
145 | */ | ||
146 | static void | ||
147 | cps_loop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
148 | |||
149 | |||
150 | /** | ||
151 | * Callback invoked with the status of the last operation. Reports to the | ||
152 | * user and then runs the next phase in the FSM. | ||
153 | * | ||
154 | * @param cls pointer to "const char*" identifying service that was manipulated | ||
155 | * @param result result of the operation | ||
156 | */ | ||
157 | static void | ||
158 | confirm_cb (void *cls, | ||
159 | enum GNUNET_ARM_ProcessStatus result) | ||
160 | { | ||
161 | const char *service = cls; | ||
162 | |||
163 | switch (result) | ||
164 | { | ||
165 | case GNUNET_ARM_PROCESS_UNKNOWN: | ||
166 | FPRINTF (stderr, _("Service `%s' is unknown to ARM.\n"), service); | ||
167 | ret = 1; | ||
168 | break; | ||
169 | case GNUNET_ARM_PROCESS_DOWN: | ||
170 | if (quiet != GNUNET_YES) | ||
171 | FPRINTF (stdout, _("Service `%s' has been stopped.\n"), service); | ||
172 | break; | ||
173 | case GNUNET_ARM_PROCESS_ALREADY_RUNNING: | ||
174 | FPRINTF (stderr, _("Service `%s' was already running.\n"), service); | ||
175 | ret = 1; | ||
176 | break; | ||
177 | case GNUNET_ARM_PROCESS_STARTING: | ||
178 | if (quiet != GNUNET_YES) | ||
179 | FPRINTF (stdout, _("Service `%s' has been started.\n"), service); | ||
180 | break; | ||
181 | case GNUNET_ARM_PROCESS_ALREADY_STOPPING: | ||
182 | FPRINTF (stderr, _("Service `%s' was already being stopped.\n"), service); | ||
183 | ret = 1; | ||
184 | break; | ||
185 | case GNUNET_ARM_PROCESS_ALREADY_DOWN: | ||
186 | FPRINTF (stderr, _("Service `%s' was already not running.\n"), service); | ||
187 | ret = 1; | ||
188 | break; | ||
189 | case GNUNET_ARM_PROCESS_SHUTDOWN: | ||
190 | FPRINTF (stderr, "%s", _("Request ignored as ARM is shutting down.\n")); | ||
191 | ret = 1; | ||
192 | break; | ||
193 | case GNUNET_ARM_PROCESS_COMMUNICATION_ERROR: | ||
194 | FPRINTF (stderr, "%s", _("Error communicating with ARM service.\n")); | ||
195 | ret = 1; | ||
196 | break; | ||
197 | case GNUNET_ARM_PROCESS_COMMUNICATION_TIMEOUT: | ||
198 | FPRINTF (stderr, "%s", _("Timeout communicating with ARM service.\n")); | ||
199 | ret = 1; | ||
200 | break; | ||
201 | case GNUNET_ARM_PROCESS_FAILURE: | ||
202 | FPRINTF (stderr, "%s", _("Operation failed.\n")); | ||
203 | ret = 1; | ||
204 | break; | ||
205 | default: | ||
206 | FPRINTF (stderr, "%s", _("Unknown response code from ARM.\n")); | ||
207 | break; | ||
208 | } | ||
209 | GNUNET_SCHEDULER_add_now (&cps_loop, NULL); | ||
210 | } | ||
211 | |||
212 | |||
213 | /** | ||
214 | * Callback invoked with the list of running services. | ||
215 | * Reports to the user and then runs the next phase in the FSM. | ||
216 | * | ||
217 | * @param cls currently not used | ||
218 | * @param result result of the operation | ||
219 | * @param count number of running services | ||
220 | * @param list copy of the list of running services | ||
221 | */ | ||
222 | static void | ||
223 | list_cb (void *cls, int result, unsigned int count, const char *const*list) | ||
224 | { | ||
225 | unsigned int i; | ||
226 | |||
227 | if ( (result != GNUNET_YES) || (NULL == list) ) | ||
228 | { | ||
229 | FPRINTF (stderr, "%s", _("Error communicating with ARM. ARM not running?\n")); | ||
230 | return; | ||
231 | } | ||
232 | FPRINTF (stdout, "%s", _("Running services:\n")); | ||
233 | for (i=0; i<count; i++) | ||
234 | FPRINTF (stdout, "%s\n", list[i]); | ||
235 | } | ||
236 | |||
237 | |||
238 | /** | ||
239 | * Attempts to delete configuration file and SERVICEHOME | 145 | * Attempts to delete configuration file and SERVICEHOME |
240 | * on arm shutdown provided the end and delete options | 146 | * on arm shutdown provided the end and delete options |
241 | * were specified when gnunet-arm was run. | 147 | * were specified when gnunet-arm was run. |
@@ -273,7 +179,9 @@ static void | |||
273 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 179 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
274 | { | 180 | { |
275 | GNUNET_ARM_disconnect (h); | 181 | GNUNET_ARM_disconnect (h); |
182 | GNUNET_ARM_monitor_disconnect (m); | ||
276 | h = NULL; | 183 | h = NULL; |
184 | m = NULL; | ||
277 | if ((end == GNUNET_YES) && (delete == GNUNET_YES)) | 185 | if ((end == GNUNET_YES) && (delete == GNUNET_YES)) |
278 | delete_files (); | 186 | delete_files (); |
279 | GNUNET_CONFIGURATION_destroy (cfg); | 187 | GNUNET_CONFIGURATION_destroy (cfg); |
@@ -281,68 +189,248 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
281 | } | 189 | } |
282 | 190 | ||
283 | 191 | ||
192 | static const char * | ||
193 | req_string (enum GNUNET_ARM_RequestStatus rs) | ||
194 | { | ||
195 | switch (rs) | ||
196 | { | ||
197 | case GNUNET_ARM_REQUEST_SENT_OK: | ||
198 | return _("Message was sent successfully"); | ||
199 | case GNUNET_ARM_REQUEST_CONFIGURATION_ERROR: | ||
200 | return _("Misconfiguration (can't connect to the ARM service)"); | ||
201 | case GNUNET_ARM_REQUEST_DISCONNECTED: | ||
202 | return _("We disconnected from ARM before we could send a request"); | ||
203 | case GNUNET_ARM_REQUEST_BUSY: | ||
204 | return _("ARM API is busy"); | ||
205 | case GNUNET_ARM_REQUEST_TOO_LONG: | ||
206 | return _("Request doesn't fit into a message"); | ||
207 | case GNUNET_ARM_REQUEST_TIMEOUT: | ||
208 | return _("Request timed out"); | ||
209 | default: | ||
210 | return _("Unknown request status"); | ||
211 | } | ||
212 | } | ||
213 | |||
214 | static const char * | ||
215 | ret_string (enum GNUNET_ARM_Result result) | ||
216 | { | ||
217 | switch (result) | ||
218 | { | ||
219 | case GNUNET_ARM_RESULT_STOPPED: | ||
220 | return _("%s is stopped"); | ||
221 | case GNUNET_ARM_RESULT_STARTING: | ||
222 | return _("%s is starting"); | ||
223 | case GNUNET_ARM_RESULT_IS_STARTING_ALREADY: | ||
224 | return _("%s is starting already"); | ||
225 | case GNUNET_ARM_RESULT_IS_STOPPING_ALREADY: | ||
226 | return _("%s is stopping already"); | ||
227 | case GNUNET_ARM_RESULT_IS_STARTED_ALREADY: | ||
228 | return _("%s is started already"); | ||
229 | case GNUNET_ARM_RESULT_IS_STOPPED_ALREADY: | ||
230 | return _("%s is stopped already"); | ||
231 | case GNUNET_ARM_RESULT_IS_NOT_KNOWN: | ||
232 | return _("%s service is not known to ARM"); | ||
233 | case GNUNET_ARM_RESULT_START_FAILED: | ||
234 | return _("%s service failed to start"); | ||
235 | case GNUNET_ARM_RESULT_IN_SHUTDOWN: | ||
236 | return _("%s service can't be started because ARM is shutting down"); | ||
237 | default: | ||
238 | return _("Unknown result code."); | ||
239 | } | ||
240 | } | ||
241 | |||
242 | static void action_loop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
243 | |||
284 | /** | 244 | /** |
285 | * Main function that will be run by the scheduler. | 245 | * Function called whenever we connect to or disconnect from ARM. |
286 | * | 246 | * |
287 | * @param cls closure | 247 | * @param cls closure |
288 | * @param args remaining command-line arguments | 248 | * @param connected GNUNET_YES if connected, GNUNET_NO if disconnected |
289 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | 249 | * @param error GNUNET_YES if we encountered a permanent error, and there |
290 | * @param c configuration | 250 | * will be no re-connection. |
291 | */ | 251 | */ |
252 | void | ||
253 | conn_status (void *cls, struct GNUNET_ARM_Handle *arm, unsigned char connected, unsigned char error) | ||
254 | { | ||
255 | if (GNUNET_YES == error) | ||
256 | { | ||
257 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
258 | _("Fatal error initializing ARM API.\n")); | ||
259 | GNUNET_SCHEDULER_shutdown (); | ||
260 | return; | ||
261 | } | ||
262 | /* | ||
263 | if (connected) | ||
264 | GNUNET_SCHEDULER_add_now (action_loop, NULL); | ||
265 | */ | ||
266 | } | ||
267 | |||
268 | |||
292 | static void | 269 | static void |
293 | run (void *cls, char *const *args, const char *cfgfile, | 270 | term_callback (void *cls, struct GNUNET_ARM_Handle *arm, |
294 | const struct GNUNET_CONFIGURATION_Handle *c) | 271 | enum GNUNET_ARM_RequestStatus rs, const char *service, |
272 | enum GNUNET_ARM_Result result) | ||
295 | { | 273 | { |
296 | char *armconfig; | 274 | if (GNUNET_ARM_REQUEST_SENT_OK != rs) |
275 | { | ||
276 | char *msg; | ||
277 | GNUNET_asprintf (&msg, _("Failed to send a request to kill the `%s' service: %%s\n"), term); | ||
278 | FPRINTF (stdout, msg, req_string (rs)); | ||
279 | GNUNET_free (msg); | ||
280 | GNUNET_SCHEDULER_shutdown (); | ||
281 | } | ||
282 | if ((GNUNET_ARM_RESULT_STOPPED == result) || | ||
283 | (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY == result)) | ||
284 | { | ||
285 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service %s shutdown successful\n", term); | ||
286 | term = NULL; | ||
287 | GNUNET_SCHEDULER_add_now (action_loop, NULL); | ||
288 | } | ||
289 | else | ||
290 | { | ||
291 | char *msg; | ||
292 | GNUNET_asprintf (&msg, _("Failed to kill the `%s' service: %%s\n"), term); | ||
293 | FPRINTF (stdout, msg, ret_string (result)); | ||
294 | GNUNET_free (msg); | ||
295 | GNUNET_SCHEDULER_shutdown (); | ||
296 | } | ||
297 | } | ||
297 | 298 | ||
298 | cfg = GNUNET_CONFIGURATION_dup (c); | 299 | static void |
299 | config_file = cfgfile; | 300 | end_callback (void *cls, struct GNUNET_ARM_Handle *arm, |
300 | if (GNUNET_CONFIGURATION_get_value_string | 301 | enum GNUNET_ARM_RequestStatus rs, const char *service, |
301 | (cfg, "PATHS", "SERVICEHOME", &dir) != GNUNET_OK) | 302 | enum GNUNET_ARM_Result result) |
303 | { | ||
304 | if (GNUNET_ARM_REQUEST_SENT_OK != rs) | ||
302 | { | 305 | { |
303 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | 306 | char *msg; |
304 | "PATHS", "SERVICEHOME"); | 307 | GNUNET_asprintf (&msg, "%s", _("Failed to send a stop request to the ARM service: %%s\n")); |
305 | return; | 308 | FPRINTF (stdout, msg, req_string (rs)); |
306 | } | 309 | GNUNET_free (msg); |
307 | if (NULL != cfgfile) | 310 | GNUNET_SCHEDULER_shutdown (); |
311 | } | ||
312 | if ((GNUNET_ARM_RESULT_STOPPING == result) || | ||
313 | (GNUNET_ARM_RESULT_STOPPED == result) || | ||
314 | (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY == result)) | ||
308 | { | 315 | { |
309 | if (GNUNET_OK != | 316 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM service shutdown successful\n"); |
310 | GNUNET_CONFIGURATION_get_value_filename (cfg, "arm", "CONFIG", | 317 | end = 0; |
311 | &armconfig)) | 318 | if (restart) |
312 | { | 319 | { |
313 | GNUNET_CONFIGURATION_set_value_string (cfg, "arm", "CONFIG", | 320 | restart = 0; |
314 | cfgfile); | 321 | start = 1; |
322 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initiating an ARM restart\n"); | ||
315 | } | 323 | } |
316 | else | 324 | GNUNET_SCHEDULER_add_now (action_loop, NULL); |
317 | GNUNET_free (armconfig); | ||
318 | } | 325 | } |
319 | if (NULL == (h = GNUNET_ARM_connect (cfg, NULL))) | 326 | else |
320 | { | 327 | { |
321 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 328 | char *msg; |
322 | _("Fatal error initializing ARM API.\n")); | 329 | GNUNET_asprintf (&msg, "%s", _("Failed to stop the ARM service: %%s\n")); |
323 | ret = 1; | 330 | FPRINTF (stdout, msg, ret_string (result)); |
324 | GNUNET_CONFIGURATION_destroy (cfg); | 331 | GNUNET_free (msg); |
325 | cfg = NULL; | 332 | GNUNET_SCHEDULER_shutdown (); |
333 | } | ||
334 | } | ||
335 | |||
336 | static void | ||
337 | start_callback (void *cls, struct GNUNET_ARM_Handle *arm, | ||
338 | enum GNUNET_ARM_RequestStatus rs, const char *service, | ||
339 | enum GNUNET_ARM_Result result) | ||
340 | { | ||
341 | if (GNUNET_ARM_REQUEST_SENT_OK != rs) | ||
342 | { | ||
343 | char *msg; | ||
344 | GNUNET_asprintf (&msg, "%s", _("Failed to start the ARM service: %%s\n")); | ||
345 | FPRINTF (stdout, msg, req_string (rs)); | ||
346 | GNUNET_free (msg); | ||
347 | GNUNET_SCHEDULER_shutdown (); | ||
348 | } | ||
349 | if ((GNUNET_ARM_RESULT_STARTING == result) || | ||
350 | (GNUNET_ARM_RESULT_IS_STARTED_ALREADY == result)) | ||
351 | { | ||
352 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM service [re]start successful\n"); | ||
353 | start = 0; | ||
354 | GNUNET_SCHEDULER_add_now (action_loop, NULL); | ||
355 | } | ||
356 | else | ||
357 | { | ||
358 | char *msg; | ||
359 | GNUNET_asprintf (&msg, "%s", _("Failed to start the ARM service: %%s\n")); | ||
360 | FPRINTF (stdout, msg, ret_string (result)); | ||
361 | GNUNET_free (msg); | ||
362 | GNUNET_SCHEDULER_shutdown (); | ||
363 | } | ||
364 | } | ||
365 | |||
366 | |||
367 | static void | ||
368 | init_callback (void *cls, struct GNUNET_ARM_Handle *arm, | ||
369 | enum GNUNET_ARM_RequestStatus rs, const char *service, | ||
370 | enum GNUNET_ARM_Result result) | ||
371 | { | ||
372 | if (GNUNET_ARM_REQUEST_SENT_OK != rs) | ||
373 | { | ||
374 | char *msg; | ||
375 | GNUNET_asprintf (&msg, _("Failed to send a request to start the `%s' service: %%s\n"), init); | ||
376 | FPRINTF (stdout, msg, req_string (rs)); | ||
377 | GNUNET_free (msg); | ||
378 | GNUNET_SCHEDULER_shutdown (); | ||
379 | } | ||
380 | if ((GNUNET_ARM_RESULT_STARTING == result) || | ||
381 | (GNUNET_ARM_RESULT_IS_STARTED_ALREADY == result)) | ||
382 | { | ||
383 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service %s [re]start successful\n", init); | ||
384 | init = NULL; | ||
385 | GNUNET_SCHEDULER_add_now (action_loop, NULL); | ||
386 | } | ||
387 | else | ||
388 | { | ||
389 | char *msg; | ||
390 | GNUNET_asprintf (&msg, _("Failed to start the `%s' service: %%s\n"), init); | ||
391 | FPRINTF (stdout, msg, ret_string (result)); | ||
392 | GNUNET_free (msg); | ||
393 | GNUNET_SCHEDULER_shutdown (); | ||
394 | } | ||
395 | } | ||
396 | |||
397 | |||
398 | static void | ||
399 | list_callback (void *cls, struct GNUNET_ARM_Handle *arm, | ||
400 | enum GNUNET_ARM_RequestStatus rs, unsigned int count, | ||
401 | const char *const*list) | ||
402 | { | ||
403 | unsigned int i; | ||
404 | if (GNUNET_ARM_REQUEST_SENT_OK != rs) | ||
405 | { | ||
406 | char *msg; | ||
407 | GNUNET_asprintf (&msg, "%s", _("Failed to request a list of services: %%s\n")); | ||
408 | FPRINTF (stdout, msg, req_string (rs)); | ||
409 | GNUNET_free (msg); | ||
410 | GNUNET_SCHEDULER_shutdown (); | ||
411 | } | ||
412 | if (NULL == list) | ||
413 | { | ||
414 | FPRINTF (stderr, "%s", _("Error communicating with ARM. ARM not running?\n")); | ||
326 | return; | 415 | return; |
327 | } | 416 | } |
328 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | 417 | FPRINTF (stdout, "%s", _("Running services:\n")); |
329 | &shutdown_task, NULL); | 418 | for (i = 0; i < count; i++) |
330 | GNUNET_SCHEDULER_add_now (&cps_loop, NULL); | 419 | FPRINTF (stdout, "%s\n", list[i]); |
331 | } | 420 | } |
332 | 421 | ||
333 | 422 | ||
334 | /** | 423 | /** |
335 | * Main continuation-passing-style loop. Runs the various | 424 | * Main action loop. Runs the various |
336 | * jobs that we've been asked to do in order. | 425 | * jobs that we've been asked to do in order. |
337 | * | 426 | * |
338 | * @param cls closure, unused | 427 | * @param cls closure, unused |
339 | * @param tc context, unused | 428 | * @param tc context, unused |
340 | */ | 429 | */ |
341 | static void | 430 | static void |
342 | cps_loop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 431 | action_loop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
343 | { | 432 | { |
344 | if (NULL == h) | 433 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Running requested actions\n"); |
345 | return; | ||
346 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 434 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
347 | return; | 435 | return; |
348 | while (1) | 436 | while (1) |
@@ -352,82 +440,54 @@ cps_loop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
352 | case 0: | 440 | case 0: |
353 | if (NULL != term) | 441 | if (NULL != term) |
354 | { | 442 | { |
355 | GNUNET_ARM_stop_service (h, term, | 443 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Termination action\n"); |
356 | (0 == | 444 | GNUNET_ARM_request_service_stop (h, term, (0 == |
357 | timeout.rel_value) ? STOP_TIMEOUT : | 445 | timeout.rel_value) ? STOP_TIMEOUT : timeout, |
358 | timeout, &confirm_cb, term); | 446 | term_callback, NULL); |
359 | return; | 447 | return; |
360 | } | 448 | } |
361 | break; | 449 | break; |
362 | case 1: | 450 | case 1: |
363 | if ((end) || (restart)) | 451 | if (end || restart) |
364 | { | 452 | { |
365 | GNUNET_ARM_stop_service (h, "arm", | 453 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "End action\n"); |
366 | (0 == | 454 | GNUNET_ARM_request_service_stop (h, "arm", (0 == |
367 | timeout.rel_value) ? STOP_TIMEOUT_ARM | 455 | timeout.rel_value) ? STOP_TIMEOUT_ARM : timeout, |
368 | : timeout, &confirm_cb, "arm"); | 456 | end_callback, NULL); |
369 | return; | 457 | return; |
370 | } | 458 | } |
371 | break; | 459 | break; |
372 | case 2: | 460 | case 2: |
373 | if (start) | 461 | if (start) |
374 | { | 462 | { |
375 | GNUNET_ARM_start_service (h, "arm", | 463 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start action\n"); |
376 | (no_stdout ? 0 : GNUNET_OS_INHERIT_STD_OUT) | | 464 | GNUNET_ARM_request_service_start (h, "arm", |
377 | (no_stderr ? 0 : GNUNET_OS_INHERIT_STD_ERR), | 465 | (no_stdout ? 0 : GNUNET_OS_INHERIT_STD_OUT) | |
378 | (0 == | 466 | (no_stderr ? 0 : GNUNET_OS_INHERIT_STD_ERR), |
379 | timeout.rel_value) ? START_TIMEOUT : | 467 | (0 == timeout.rel_value) ? START_TIMEOUT: timeout, |
380 | timeout, &confirm_cb, "arm"); | 468 | start_callback, NULL); |
381 | return; | 469 | return; |
382 | } | 470 | } |
383 | break; | 471 | break; |
384 | case 3: | 472 | case 3: |
385 | if (NULL != init) | 473 | if (NULL != init) |
386 | { | ||
387 | GNUNET_ARM_start_service (h, init, | ||
388 | (no_stdout ? 0 : GNUNET_OS_INHERIT_STD_OUT) | | ||
389 | (no_stderr ? 0 : GNUNET_OS_INHERIT_STD_ERR), | ||
390 | (0 == | ||
391 | timeout.rel_value) ? START_TIMEOUT : | ||
392 | timeout, &confirm_cb, init); | ||
393 | return; | ||
394 | } | ||
395 | break; | ||
396 | case 4: | ||
397 | if (restart) | ||
398 | { | 474 | { |
399 | GNUNET_ARM_disconnect (h); | 475 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initialization action\n"); |
400 | phase = 0; | 476 | GNUNET_ARM_request_service_start (h, init, GNUNET_OS_INHERIT_STD_NONE, |
401 | end = 0; | 477 | (0 == timeout.rel_value) ? STOP_TIMEOUT : timeout, |
402 | start = 1; | 478 | init_callback, NULL); |
403 | restart = 0; | 479 | return; |
404 | if (NULL == (h = GNUNET_ARM_connect (cfg, NULL))) | ||
405 | { | ||
406 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
407 | _("Fatal error initializing ARM API.\n")); | ||
408 | ret = 1; | ||
409 | return; | ||
410 | } | ||
411 | GNUNET_SCHEDULER_add_now (&cps_loop, NULL); | ||
412 | return; | ||
413 | } | 480 | } |
414 | break; | 481 | break; |
415 | case 5: | 482 | case 4: |
416 | if (list) | 483 | if (list) |
417 | { | 484 | { |
418 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 485 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
419 | "Going to list all running services controlled by ARM.\n"); | 486 | "Going to list all running services controlled by ARM.\n"); |
420 | 487 | ||
421 | if (NULL == h) | 488 | GNUNET_ARM_request_service_list (h, |
422 | { | 489 | (0 == timeout.rel_value) ? LIST_TIMEOUT : timeout, |
423 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 490 | list_callback, &list); |
424 | _("Fatal error initializing ARM API.\n")); | ||
425 | return; | ||
426 | } | ||
427 | GNUNET_ARM_list_running_services (h, | ||
428 | (0 == | ||
429 | timeout.rel_value) ? LIST_TIMEOUT : | ||
430 | timeout, &list_cb, NULL); | ||
431 | return; | 491 | return; |
432 | } | 492 | } |
433 | /* Fall through */ | 493 | /* Fall through */ |
@@ -440,6 +500,89 @@ cps_loop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
440 | 500 | ||
441 | 501 | ||
442 | /** | 502 | /** |
503 | * Function called when a service starts or stops. | ||
504 | * | ||
505 | * @param cls closure | ||
506 | * @param service service name | ||
507 | * @param status status of the service | ||
508 | */ | ||
509 | static void | ||
510 | srv_status (void *cls, struct GNUNET_ARM_MonitorHandle *arm, | ||
511 | const char *service, enum GNUNET_ARM_ServiceStatus status) | ||
512 | { | ||
513 | const char *msg; | ||
514 | switch (status) | ||
515 | { | ||
516 | case GNUNET_ARM_SERVICE_MONITORING_STARTED: | ||
517 | msg = _("Began monitoring ARM for service status changes\n"); | ||
518 | break; | ||
519 | case GNUNET_ARM_SERVICE_STOPPED: | ||
520 | msg = _("Stopped %s.\n"); | ||
521 | break; | ||
522 | case GNUNET_ARM_SERVICE_STARTING: | ||
523 | msg = _("Starting %s...\n"); | ||
524 | break; | ||
525 | case GNUNET_ARM_SERVICE_STOPPING: | ||
526 | msg = _("Stopping %s...\n"); | ||
527 | break; | ||
528 | default: | ||
529 | msg = NULL; | ||
530 | break; | ||
531 | } | ||
532 | if (NULL != msg) | ||
533 | FPRINTF (stderr, msg, service); | ||
534 | else | ||
535 | FPRINTF (stderr, _("Unknown status %u for service %s.\n"), status, service); | ||
536 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got service %s status %u\n", service, status); | ||
537 | } | ||
538 | |||
539 | |||
540 | /** | ||
541 | * Main function that will be run by the scheduler. | ||
542 | * | ||
543 | * @param cls closure | ||
544 | * @param args remaining command-line arguments | ||
545 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
546 | * @param c configuration | ||
547 | */ | ||
548 | static void | ||
549 | run (void *cls, char *const *args, const char *cfgfile, | ||
550 | const struct GNUNET_CONFIGURATION_Handle *c) | ||
551 | { | ||
552 | char *armconfig; | ||
553 | |||
554 | cfg = GNUNET_CONFIGURATION_dup (c); | ||
555 | config_file = cfgfile; | ||
556 | if (GNUNET_CONFIGURATION_get_value_string | ||
557 | (cfg, "PATHS", "SERVICEHOME", &dir) != GNUNET_OK) | ||
558 | { | ||
559 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | ||
560 | "PATHS", "SERVICEHOME"); | ||
561 | return; | ||
562 | } | ||
563 | if (NULL != cfgfile) | ||
564 | { | ||
565 | if (GNUNET_OK != | ||
566 | GNUNET_CONFIGURATION_get_value_filename (cfg, "arm", "CONFIG", | ||
567 | &armconfig)) | ||
568 | { | ||
569 | GNUNET_CONFIGURATION_set_value_string (cfg, "arm", "CONFIG", | ||
570 | cfgfile); | ||
571 | } | ||
572 | else | ||
573 | GNUNET_free (armconfig); | ||
574 | } | ||
575 | h = GNUNET_ARM_alloc (cfg); | ||
576 | m = GNUNET_ARM_monitor_alloc (cfg); | ||
577 | GNUNET_ARM_connect (h, conn_status, NULL); | ||
578 | GNUNET_ARM_monitor (m, srv_status, NULL); | ||
579 | GNUNET_SCHEDULER_add_now (action_loop, NULL); | ||
580 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | ||
581 | shutdown_task, NULL); | ||
582 | } | ||
583 | |||
584 | |||
585 | /** | ||
443 | * The main function to obtain arm from gnunetd. | 586 | * The main function to obtain arm from gnunetd. |
444 | * | 587 | * |
445 | * @param argc number of arguments from the command line | 588 | * @param argc number of arguments from the command line |