static int pkg_load_message_from_file(int fd, struct pkg *pkg, const char *path) { char *buf = NULL; off_t size = 0; int ret; ucl_object_t *obj; assert(pkg != NULL); assert(path != NULL); if (faccessat(fd, path, F_OK, 0) == 0) { pkg_debug(1, "Reading message: '%s'", path); if ((ret = file_to_bufferat(fd, path, &buf, &size)) != EPKG_OK) { return (ret); } if (*buf == '[') { ret = pkg_message_from_str(pkg, buf, size); free(buf); return (ret); } else { obj = ucl_object_fromstring_common(buf, size, UCL_STRING_RAW|UCL_STRING_TRIM); ret = pkg_message_from_ucl(pkg, obj); ucl_object_unref(obj); free(buf); return (ret); } } return (EPKG_FATAL); }
static void attempt_to_merge(int rootfd, struct pkg_config_file *rcf, struct pkg *local, bool merge) { const struct pkg_file *lf = NULL; struct sbuf *newconf; struct pkg_config_file *lcf = NULL; char *localconf = NULL; off_t sz; char *localsum; if (rcf == NULL) { pkg_debug(3, "No remote config file"); return; } if (local == NULL) { pkg_debug(3, "No local package"); return; } if (!pkg_is_config_file(local, rcf->path, &lf, &lcf)) { pkg_debug(3, "No local package"); return; } if (lcf->content == NULL) { pkg_debug(3, "Empty configuration content for local package"); return; } pkg_debug(1, "Config file found %s", rcf->path); if (file_to_bufferat(rootfd, RELATIVE_PATH(rcf->path), &localconf, &sz) != EPKG_OK) return; pkg_debug(2, "size: %d vs %d", sz, strlen(lcf->content)); if (sz == strlen(lcf->content)) { pkg_debug(2, "Ancient vanilla and deployed conf are the same size testing checksum"); localsum = pkg_checksum_data(localconf, sz, PKG_HASH_TYPE_SHA256_HEX); if (localsum && strcmp(localsum, lf->sum) == 0) { pkg_debug(2, "Checksum are the same %d", strlen(localconf)); free(localconf); free(localsum); return; } free(localsum); pkg_debug(2, "Checksum are different %d", strlen(localconf)); } rcf->status = MERGE_FAILED; if (!merge) { free(localconf); return; } pkg_debug(1, "Attempting to merge %s", rcf->path); newconf = sbuf_new_auto(); if (merge_3way(lcf->content, localconf, rcf->content, newconf) != 0) { pkg_emit_error("Impossible to merge configuration file"); } else { sbuf_finish(newconf); rcf->newcontent = strdup(sbuf_data(newconf)); rcf->status = MERGE_SUCCESS; } sbuf_delete(newconf); free(localconf); }