| 301 | } |
| 302 | |
| 303 | static bool cli_activation_log_event(cli_activation_production_context_t *context, |
| 304 | const char *phase, const char *detail) { |
| 305 | if (!context || !context->activation_log || !phase) { |
| 306 | return false; |
| 307 | } |
| 308 | yyjson_mut_doc *document = yyjson_mut_doc_new(NULL); |
| 309 | yyjson_mut_val *root = document ? yyjson_mut_obj(document) : NULL; |
| 310 | if (!document || !root) { |
| 311 | yyjson_mut_doc_free(document); |
| 312 | return false; |
| 313 | } |
| 314 | yyjson_mut_doc_set_root(document, root); |
| 315 | bool encoded = |
| 316 | yyjson_mut_obj_add_str(document, root, "event", "cbm.activation") && |
| 317 | yyjson_mut_obj_add_strcpy(document, root, "phase", phase) && |
| 318 | yyjson_mut_obj_add_strcpy(document, root, "action", |
| 319 | cli_activation_action_text(context->action)) && |
| 320 | yyjson_mut_obj_add_int(document, root, "requester_pid", |
| 321 | (int64_t)cli_activation_process_id()) && |
| 322 | yyjson_mut_obj_add_int(document, root, "timestamp_unix_s", (int64_t)time(NULL)) && |
| 323 | yyjson_mut_obj_add_str(document, root, "source_version", CBM_VERSION) && |
| 324 | yyjson_mut_obj_add_strcpy( |
| 325 | document, root, "source_build", |
| 326 | context->identity.build_fingerprint ? context->identity.build_fingerprint : "") && |
| 327 | yyjson_mut_obj_add_int(document, root, "daemon_active_clients", |
| 328 | (int64_t)context->daemon_result.active_clients) && |
| 329 | yyjson_mut_obj_add_int(document, root, "daemon_active_connections", |
| 330 | (int64_t)context->daemon_result.active_connections) && |
| 331 | yyjson_mut_obj_add_bool(document, root, "restart_required", true); |
| 332 | if (encoded && context->target_version && context->target_version[0]) { |
| 333 | encoded = |
| 334 | yyjson_mut_obj_add_strcpy(document, root, "target_version", context->target_version); |
| 335 | } |
| 336 | if (encoded && context->target_build && context->target_build[0]) { |
| 337 | encoded = yyjson_mut_obj_add_strcpy(document, root, "target_build", context->target_build); |
| 338 | } |
| 339 | if (encoded && detail && detail[0]) { |
| 340 | encoded = yyjson_mut_obj_add_strcpy(document, root, "detail", detail); |
| 341 | } |
| 342 | size_t json_size = 0; |
| 343 | char *json = encoded ? yyjson_mut_write(document, 0, &json_size) : NULL; |
| 344 | bool written = |
| 345 | json && json_size > 0 && fwrite(json, 1, json_size, context->activation_log) == json_size && |
| 346 | fputc('\n', context->activation_log) != EOF && fflush(context->activation_log) == 0; |
| 347 | if (written) { |
| 348 | int descriptor = cbm_fileno(context->activation_log); |
| 349 | #ifdef _WIN32 |
| 350 | written = descriptor >= 0 && _commit(descriptor) == 0; |
| 351 | #else |
| 352 | written = descriptor >= 0 && fsync(descriptor) == 0; |
| 353 | #endif |
| 354 | } |
| 355 | free(json); |
| 356 | yyjson_mut_doc_free(document); |
| 357 | return written; |
| 358 | } |
| 359 | |
| 360 | static int cli_activation_startup_lock_acquire(cli_activation_production_context_t *context) { |
no test coverage detected