| 352 | } |
| 353 | |
| 354 | static bool cli_activation_log_event(cli_activation_production_context_t *context, |
| 355 | const char *phase, const char *detail) { |
| 356 | if (!context || !context->activation_log || !phase) { |
| 357 | return false; |
| 358 | } |
| 359 | yyjson_mut_doc *document = yyjson_mut_doc_new(NULL); |
| 360 | yyjson_mut_val *root = document ? yyjson_mut_obj(document) : NULL; |
| 361 | if (!document || !root) { |
| 362 | yyjson_mut_doc_free(document); |
| 363 | return false; |
| 364 | } |
| 365 | yyjson_mut_doc_set_root(document, root); |
| 366 | bool encoded = |
| 367 | yyjson_mut_obj_add_str(document, root, "event", "cbm.activation") && |
| 368 | yyjson_mut_obj_add_strcpy(document, root, "phase", phase) && |
| 369 | yyjson_mut_obj_add_strcpy(document, root, "action", |
| 370 | cli_activation_action_text(context->action)) && |
| 371 | yyjson_mut_obj_add_int(document, root, "requester_pid", |
| 372 | (int64_t)cli_activation_process_id()) && |
| 373 | yyjson_mut_obj_add_int(document, root, "timestamp_unix_s", (int64_t)time(NULL)) && |
| 374 | yyjson_mut_obj_add_str(document, root, "source_version", CBM_VERSION) && |
| 375 | yyjson_mut_obj_add_strcpy( |
| 376 | document, root, "source_build", |
| 377 | context->identity.build_fingerprint ? context->identity.build_fingerprint : "") && |
| 378 | yyjson_mut_obj_add_int(document, root, "daemon_active_clients", |
| 379 | (int64_t)context->daemon_result.active_clients) && |
| 380 | yyjson_mut_obj_add_int(document, root, "daemon_active_connections", |
| 381 | (int64_t)context->daemon_result.active_connections) && |
| 382 | yyjson_mut_obj_add_bool(document, root, "restart_required", true); |
| 383 | if (encoded && context->target_version && context->target_version[0]) { |
| 384 | encoded = |
| 385 | yyjson_mut_obj_add_strcpy(document, root, "target_version", context->target_version); |
| 386 | } |
| 387 | if (encoded && context->target_build && context->target_build[0]) { |
| 388 | encoded = yyjson_mut_obj_add_strcpy(document, root, "target_build", context->target_build); |
| 389 | } |
| 390 | if (encoded && detail && detail[0]) { |
| 391 | encoded = yyjson_mut_obj_add_strcpy(document, root, "detail", detail); |
| 392 | } |
| 393 | size_t json_size = 0; |
| 394 | char *json = encoded ? yyjson_mut_write(document, 0, &json_size) : NULL; |
| 395 | bool written = |
| 396 | json && json_size > 0 && fwrite(json, 1, json_size, context->activation_log) == json_size && |
| 397 | fputc('\n', context->activation_log) != EOF && fflush(context->activation_log) == 0; |
| 398 | if (written) { |
| 399 | int descriptor = cbm_fileno(context->activation_log); |
| 400 | #ifdef _WIN32 |
| 401 | written = descriptor >= 0 && _commit(descriptor) == 0; |
| 402 | #else |
| 403 | written = descriptor >= 0 && fsync(descriptor) == 0; |
| 404 | #endif |
| 405 | } |
| 406 | free(json); |
| 407 | yyjson_mut_doc_free(document); |
| 408 | return written; |
| 409 | } |
| 410 | |
| 411 | static int cli_activation_startup_lock_acquire(cli_activation_production_context_t *context) { |
no test coverage detected