static char * get_checksum(const char *filename, cr_ChecksumType type, cr_Package *pkg, const char *cachedir, GError **err) { GError *tmp_err = NULL; char *checksum = NULL; char *cachefn = NULL; if (cachedir) { // Prepare cache fn char *key; cr_ChecksumCtx *ctx = cr_checksum_new(type, err); if (!ctx) return NULL; if (pkg->siggpg) cr_checksum_update(ctx, pkg->siggpg->data, pkg->siggpg->size, NULL); if (pkg->sigpgp) cr_checksum_update(ctx, pkg->sigpgp->data, pkg->sigpgp->size, NULL); if (pkg->hdrid) cr_checksum_update(ctx, pkg->hdrid, strlen(pkg->hdrid), NULL); key = cr_checksum_final(ctx, err); if (!key) return NULL; cachefn = g_strdup_printf("%s%s-%s-%"G_GINT64_FORMAT"-%"G_GINT64_FORMAT, cachedir, cr_get_filename(pkg->location_href), key, pkg->size_installed, pkg->time_file); free(key); // Try to load checksum FILE *f = fopen(cachefn, "r"); if (f) { char buf[CACHEDCHKSUM_BUFFER_LEN]; size_t readed = fread(buf, 1, CACHEDCHKSUM_BUFFER_LEN, f); if (!ferror(f) && readed > 0) { checksum = g_strndup(buf, readed); } fclose(f); } if (checksum) { g_debug("Cached checksum used: %s: \"%s\"", cachefn, checksum); goto exit; } } // Calculate checksum checksum = cr_checksum_file(filename, type, &tmp_err); if (!checksum) { g_propagate_prefixed_error(err, tmp_err, "Error while checksum calculation: "); goto exit; } // Cache the checksum value if (cachefn && !g_file_test(cachefn, G_FILE_TEST_EXISTS)) { gchar *template = g_strconcat(cachefn, "-XXXXXX", NULL);
contentStat * cr_get_compressed_content_stat(const char *filename, cr_ChecksumType checksum_type, GError **err) { GError *tmp_err = NULL; assert(filename); assert(!err || *err == NULL); if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) { g_set_error(err, CR_REPOMD_RECORD_ERROR, CRE_NOFILE, "File %s doesn't exists or not a regular file", filename); return NULL; } // Open compressed file CR_FILE *cwfile = cr_open(filename, CR_CW_MODE_READ, CR_CW_AUTO_DETECT_COMPRESSION, &tmp_err); if (!cwfile) { g_propagate_prefixed_error(err, tmp_err, "Cannot open a file %s: ", filename); return NULL; } // Read compressed file and calculate checksum and size cr_ChecksumCtx *checksum = cr_checksum_new(checksum_type, &tmp_err); if (tmp_err) { g_critical("%s: g_checksum_new() failed", __func__); g_propagate_prefixed_error(err, tmp_err, "Error while checksum calculation: "); return NULL; } gint64 size = 0; long readed; unsigned char buffer[BUFFER_SIZE]; do { readed = cr_read(cwfile, (void *) buffer, BUFFER_SIZE, &tmp_err); if (readed == CR_CW_ERR) { g_debug("%s: Error while read compressed file %s: %s", __func__, filename, tmp_err->message); g_propagate_prefixed_error(err, tmp_err, "Error while read compressed file %s: ", filename); break; } cr_checksum_update(checksum, buffer, readed, NULL); size += readed; } while (readed == BUFFER_SIZE); if (readed == CR_CW_ERR) return NULL; // Create result structure contentStat* result = g_malloc(sizeof(contentStat)); if (result) { result->checksum = cr_checksum_final(checksum, NULL); result->size = size; } else { g_set_error(err, CR_REPOMD_RECORD_ERROR, CRE_MEMORY, "Cannot allocate memory"); } cr_close(cwfile, NULL); return result; }