| 1938 | } |
| 1939 | |
| 1940 | static int cbm_upsert_json_named_mcp(const char *binary_path, const char *config_path, |
| 1941 | const char *const *object_path, size_t path_len, |
| 1942 | cbm_json_mcp_schema_t schema, const char *entry_name, |
| 1943 | const char *argument) { |
| 1944 | if (!binary_path || !config_path || !object_path || !entry_name || !entry_name[0]) { |
| 1945 | return CLI_ERR; |
| 1946 | } |
| 1947 | char *document = NULL; |
| 1948 | size_t document_length = 0U; |
| 1949 | int read_result = cbm_json_like_read_document(config_path, &document, &document_length); |
| 1950 | if (read_result < 0) { |
| 1951 | return CLI_ERR; |
| 1952 | } |
| 1953 | if (read_result == 0) { |
| 1954 | int ownership = cbm_json_mcp_snapshot_ownership( |
| 1955 | document, document_length, object_path, path_len, schema, entry_name, argument, |
| 1956 | binary_path, g_previous_managed_mcp_command); |
| 1957 | /* STALE (our exact shape, dead binary path) is repairable — that is |
| 1958 | * the update contract. Only a genuinely foreign shape refuses. */ |
| 1959 | if (ownership != CBM_JSON_LIKE_OBJECT_MATCH && ownership != CBM_JSON_LIKE_OBJECT_MISSING && |
| 1960 | ownership != CBM_JSON_MCP_OWNERSHIP_STALE) { |
| 1961 | free(document); |
| 1962 | return CLI_ERR; |
| 1963 | } |
| 1964 | } |
| 1965 | |
| 1966 | char *entry = cbm_build_json_mcp_entry(binary_path, schema, argument); |
| 1967 | if (!entry) { |
| 1968 | free(document); |
| 1969 | return CLI_ERR; |
| 1970 | } |
| 1971 | int edit_result = cbm_json_like_upsert_entry_if_unchanged( |
| 1972 | config_path, object_path, path_len, entry_name, entry, read_result == 1 ? NULL : document, |
| 1973 | document_length); |
| 1974 | free(entry); |
| 1975 | free(document); |
| 1976 | return edit_result == 0 ? CLI_OK : CLI_ERR; |
| 1977 | } |
| 1978 | |
| 1979 | static int cbm_upsert_json_mcp(const char *binary_path, const char *config_path, |
| 1980 | const char *const *object_path, size_t path_len, |
no test coverage detected