Ejemplo n.º 1
0
void
cr_xml_dump_updatecollectionpackages(xmlNodePtr collection, GSList *packages)
{
    for (GSList *elem = packages; elem; elem = g_slist_next(elem)) {
        cr_UpdateCollectionPackage *pkg = elem->data;
        xmlNodePtr package;

        package = xmlNewChild(collection, NULL, BAD_CAST "package", NULL);
        cr_xmlNewProp_c(package, BAD_CAST "name", BAD_CAST pkg->name);
        cr_xmlNewProp_c(package, BAD_CAST "version", BAD_CAST pkg->version);
        cr_xmlNewProp_c(package, BAD_CAST "release", BAD_CAST pkg->release);
        cr_xmlNewProp_c(package, BAD_CAST "epoch", BAD_CAST pkg->epoch);
        cr_xmlNewProp_c(package, BAD_CAST "arch", BAD_CAST pkg->arch);
        cr_xmlNewProp_c(package, BAD_CAST "src", BAD_CAST pkg->src);
        cr_xmlNewTextChild_c(package, NULL, BAD_CAST "filename",
                             BAD_CAST pkg->filename);

        if (pkg->sum) {
            xmlNodePtr sum;
            sum = cr_xmlNewTextChild_c(package,
                                       NULL,
                                       BAD_CAST "sum",
                                       BAD_CAST pkg->sum);
            cr_xmlNewProp_c(sum,
                            BAD_CAST "type",
                            BAD_CAST cr_checksum_name_str(pkg->sum_type));
        }

        if (pkg->reboot_suggested)
            xmlNewChild(package, NULL, BAD_CAST "reboot_suggested", NULL);
    }
}
static gboolean
cmd_options_to_task(GSList **modifyrepotasks,
                    RawCmdOptions *options,
                    gchar *metadatapath,
                    GError **err)
{
    assert(modifyrepotasks);
    assert(!err || *err == NULL);

    if (!options)
        return TRUE;

    //assert(metadatapath || options->remove);

    if (options->remove)
        g_debug("Preparing remove-task for: %s", options->remove);
    else
        g_debug("Preparing task for: %s", metadatapath);

    if (metadatapath && !g_file_test(metadatapath, G_FILE_TEST_IS_REGULAR)) {
        g_set_error(err, ERR_DOMAIN, CRE_ERROR,
                    "File \"%s\" is not regular file or doesn't exists",
                    metadatapath);
        return FALSE;
    }

    if (options->remove)
        metadatapath = options->remove;

    cr_ModifyRepoTask *task = cr_modifyrepotask_new();
    task->path = cr_safe_string_chunk_insert_null(task->chunk, metadatapath);
    task->type = cr_safe_string_chunk_insert_null(task->chunk, options->mdtype);
    task->remove = (options->remove) ? TRUE : FALSE;
    task->compress = options->compress;
    task->compress_type = cr_compression_type(options->compress_type);
    task->unique_md_filenames = options->unique_md_filenames;
    task->checksum_type = cr_checksum_type(options->checksum);
    task->new_name = cr_safe_string_chunk_insert_null(task->chunk,
                                                      options->new_name);
    task->zck = options->zck;
    task->zck_dict_dir = options->zck_dict_dir;

    *modifyrepotasks = g_slist_append(*modifyrepotasks, task);

    g_debug("Task: [path: %s, type: %s, remove: %d, compress: %d, "
            "compress_type: %d (%s), unique_md_filenames: %d, "
            "checksum_type: %d (%s), new_name: %s]",
            task->path, task->type, task->remove, task->compress,
            task->compress_type, cr_compression_suffix(task->compress_type),
            task->unique_md_filenames, task->checksum_type,
            cr_checksum_name_str(task->checksum_type), task->new_name);

    return TRUE;
}
Ejemplo n.º 3
0
PyObject *
py_checksum_name_str(PyObject *self, PyObject *args)
{
    int type;

    CR_UNUSED(self);

    if (!PyArg_ParseTuple(args, "i:py_checksum_name_Str", &type))
        return NULL;

    return PyStringOrNone_FromString(cr_checksum_name_str(type));
}
Ejemplo n.º 4
0
void
cr_repomd_record_load_contentstat(cr_RepomdRecord *record,
                                  cr_ContentStat *stats)
{
    if (!stats)
        return;

    record->checksum_open = cr_safe_string_chunk_insert(record->chunk,
                                                        stats->checksum);
    record->checksum_open_type = cr_safe_string_chunk_insert(record->chunk,
                                cr_checksum_name_str(stats->checksum_type));
    record->size_open = stats->size;
}
Ejemplo n.º 5
0
static gboolean
generate_sqlite_from_xml(const gchar *path,
                         cr_CompressionType compression_type,
                         cr_ChecksumType checksum_type,
                         gboolean local_sqlite,
                         gboolean force,
                         gboolean keep_old,
                         GError **err)
{
    _cleanup_free_ gchar *in_dir       = NULL;  // path/to/repo/
    _cleanup_free_ gchar *in_repo      = NULL;  // path/to/repo/repodata/
    _cleanup_free_ gchar *out_dir      = NULL;  // path/to/out_repo/
    _cleanup_free_ gchar *out_repo     = NULL;  // path/to/out_repo/repodata/
    _cleanup_free_ gchar *tmp_out_repo = NULL;  // usually path/to/out_repo/.repodata/
    _cleanup_free_ gchar *lock_dir     = NULL;  // path/to/out_repo/.repodata/
    gboolean ret;
    GError *tmp_err = NULL;

    // Check if input dir exists
    in_dir = cr_normalize_dir_path(path);
    if (!g_file_test(in_dir, G_FILE_TEST_IS_DIR)) {
        g_set_error(err, CREATEREPO_C_ERROR, CRE_IO,
                    "Directory %s must exist\n", in_dir);
        return FALSE;
    }

    // Set other paths
    in_repo         = g_build_filename(in_dir, "repodata/", NULL);
    out_dir         = g_strdup(in_dir);
    out_repo        = g_strdup(in_repo);
    lock_dir        = g_build_filename(out_dir, ".repodata/", NULL);
    tmp_out_repo    = g_build_filename(out_dir, ".repodata/", NULL);

    // Block signals that terminates the process
    if (!cr_block_terminating_signals(err))
        return FALSE;

    // Check if lock exists & Create lock dir
    if (!cr_lock_repo(out_dir, FALSE, &lock_dir, &tmp_out_repo, err))
        return FALSE;

    // Setup cleanup handlers
    if (!cr_set_cleanup_handler(lock_dir, tmp_out_repo, err))
        return FALSE;

    // Unblock the blocked signals
    if (!cr_unblock_terminating_signals(err))
        return FALSE;

    // Locate repodata
    struct cr_MetadataLocation *md_loc = NULL;
    _cleanup_free_ gchar *pri_xml_path = NULL;
    _cleanup_free_ gchar *fil_xml_path = NULL;
    _cleanup_free_ gchar *oth_xml_path = NULL;
    _cleanup_free_ gchar *repomd_path = NULL;

    md_loc = cr_locate_metadata(in_dir, TRUE, NULL);
    if (!md_loc || !md_loc->repomd) {
        g_set_error(err, CREATEREPO_C_ERROR, CRE_NOFILE,
                    "repomd.xml doesn't exist");
        return FALSE;
    }

    repomd_path = g_build_filename(md_loc->repomd, NULL);

    if (md_loc->pri_xml_href)
        pri_xml_path = g_build_filename(md_loc->pri_xml_href, NULL);
    if (md_loc->fil_xml_href)
        fil_xml_path = g_build_filename(md_loc->fil_xml_href, NULL);
    if (md_loc->oth_xml_href)
        oth_xml_path = g_build_filename(md_loc->oth_xml_href, NULL);
    cr_metadatalocation_free(md_loc);

    // Parse repomd.xml
    int rc;
    cr_Repomd *repomd = cr_repomd_new();

    rc = cr_xml_parse_repomd(repomd_path,
                             repomd,
                             warningcb,
                             (void *) repomd_path,
                             err);
    if (rc != CRE_OK)
        return FALSE;

    // Check if DBs already exist or not
    gboolean dbs_already_exist = FALSE;

    if (cr_repomd_get_record(repomd, "primary_db")
        || cr_repomd_get_record(repomd, "filename_db")
        || cr_repomd_get_record(repomd, "other_db"))
    {
        dbs_already_exist = TRUE;
    }

    if (dbs_already_exist && !force) {
        g_set_error(err, CREATEREPO_C_ERROR, CRE_ERROR,
                    "Repository already has sqlitedb present "
                    "in repomd.xml (You may use --force)");
        return FALSE;
    }

    // Auto-detect used checksum algorithm if not specified explicitly
    if (checksum_type == CR_CHECKSUM_UNKNOWN) {
        cr_RepomdRecord *rec = cr_repomd_get_record(repomd, "primary");

        if (!rec) {
            g_set_error(err, CREATEREPO_C_ERROR, CRE_ERROR,
                        "repomd.xml is missing primary metadata");
            return FALSE;
        }

        if (rec->checksum_type)
            checksum_type = cr_checksum_type(rec->checksum_type);
        else if (rec->checksum_open_type)
            checksum_type = cr_checksum_type(rec->checksum_open_type);

        if (checksum_type == CR_CHECKSUM_UNKNOWN) {
            g_debug("Cannot auto-detect checksum type, using default %s",
                    cr_checksum_name_str(DEFAULT_CHECKSUM));
            checksum_type = DEFAULT_CHECKSUM;
        }
    }

    // Open sqlite databases
    _cleanup_free_ gchar *pri_db_filename = NULL;
    _cleanup_free_ gchar *fil_db_filename = NULL;
    _cleanup_free_ gchar *oth_db_filename = NULL;
    cr_SqliteDb *pri_db = NULL;
    cr_SqliteDb *fil_db = NULL;
    cr_SqliteDb *oth_db = NULL;

    _cleanup_file_close_ int pri_db_fd = -1;
    _cleanup_file_close_ int fil_db_fd = -1;
    _cleanup_file_close_ int oth_db_fd = -1;

    g_message("Preparing sqlite DBs");
    if (!local_sqlite) {
        g_debug("Creating databases");
        pri_db_filename = g_strconcat(tmp_out_repo, "/primary.sqlite", NULL);
        fil_db_filename = g_strconcat(tmp_out_repo, "/filelists.sqlite", NULL);
        oth_db_filename = g_strconcat(tmp_out_repo, "/other.sqlite", NULL);
    } else {
        g_debug("Creating databases localy");
        const gchar *tmpdir = g_get_tmp_dir();
        pri_db_filename = g_build_filename(tmpdir, "primary.XXXXXX.sqlite", NULL);
        fil_db_filename = g_build_filename(tmpdir, "filelists.XXXXXX.sqlite", NULL);
        oth_db_filename = g_build_filename(tmpdir, "other.XXXXXXX.sqlite", NULL);
        pri_db_fd = g_mkstemp(pri_db_filename);
        g_debug("%s", pri_db_filename);
        if (pri_db_fd == -1) {
            g_set_error(err, CREATEREPO_C_ERROR, CRE_IO,
                        "Cannot open %s: %s", pri_db_filename, g_strerror(errno));
            return FALSE;
        }
        fil_db_fd = g_mkstemp(fil_db_filename);
        g_debug("%s", fil_db_filename);
        if (fil_db_fd == -1) {
            g_set_error(err, CREATEREPO_C_ERROR, CRE_IO,
                        "Cannot open %s: %s", fil_db_filename, g_strerror(errno));
            return FALSE;
        }
        oth_db_fd = g_mkstemp(oth_db_filename);
        g_debug("%s", oth_db_filename);
        if (oth_db_fd == -1) {
            g_set_error(err, CREATEREPO_C_ERROR, CRE_IO,
                        "Cannot open %s: %s", oth_db_filename, g_strerror(errno));
            return FALSE;
        }
    }

    pri_db = cr_db_open_primary(pri_db_filename, err);
    if (!pri_db)
        return FALSE;

    fil_db = cr_db_open_filelists(fil_db_filename, err);
    assert(fil_db || tmp_err);
    if (!fil_db)
        return FALSE;

    oth_db = cr_db_open_other(oth_db_filename, err);
    assert(oth_db || tmp_err);
    if (!oth_db)
        return FALSE;

    // XML to Sqlite
    ret = xml_to_sqlite(pri_xml_path,
                        fil_xml_path,
                        oth_xml_path,
                        pri_db,
                        fil_db,
                        oth_db,
                        err);
    if (!ret)
        return FALSE;

    // Put checksums of XML files into Sqlite
    ret = sqlite_dbinfo_update(repomd,
                               pri_db,
                               fil_db,
                               oth_db,
                               err);
    if (!ret)
        return FALSE;

    // Close dbs
    cr_db_close(pri_db, NULL);
    cr_db_close(fil_db, NULL);
    cr_db_close(oth_db, NULL);

    // Repomd records
    cr_RepomdRecord *pri_db_rec = NULL;
    cr_RepomdRecord *fil_db_rec = NULL;
    cr_RepomdRecord *oth_db_rec = NULL;

    // Compress DB files and fill records
    ret = compress_sqlite_dbs(tmp_out_repo,
                              pri_db_filename,
                              &pri_db_rec,
                              fil_db_filename,
                              &fil_db_rec,
                              oth_db_filename,
                              &oth_db_rec,
                              compression_type,
                              checksum_type,
                              err);
    if (!ret)
        return FALSE;

    // Prepare new repomd.xml
    ret = gen_new_repomd(tmp_out_repo,
                         repomd,
                         pri_db_rec,
                         fil_db_rec,
                         oth_db_rec,
                         err);
    if (!ret)
        return FALSE;

    // Move the results (compressed DBs and repomd.xml) into in_repo
    ret = move_results(tmp_out_repo,
                       in_repo,
                       err);
    if (!ret)
        return FALSE;

    // Remove old DBs
    if (dbs_already_exist && force && !keep_old) {
        ret = remove_old_if_different(in_dir,
                                      cr_repomd_get_record(repomd, "primary_db"),
                                      pri_db_rec, err);
        if (!ret)
            return FALSE;
        ret = remove_old_if_different(in_dir,
                                      cr_repomd_get_record(repomd, "filelists_db"),
                                      fil_db_rec, err);
        if (!ret)
            return FALSE;
        ret = remove_old_if_different(in_dir,
                                      cr_repomd_get_record(repomd, "other_db"),
                                      oth_db_rec, err);
        if (!ret)
            return FALSE;
    }

    // Remove tmp_out_repo
    g_rmdir(tmp_out_repo);

    // Clean up
    cr_repomd_free(repomd);
    cr_repomd_record_free(pri_db_rec);
    cr_repomd_record_free(fil_db_rec);
    cr_repomd_record_free(oth_db_rec);

    return TRUE;
}
Ejemplo n.º 6
0
int
cr_repomd_record_compress_and_fill(cr_RepomdRecord *record,
                                   cr_RepomdRecord *crecord,
                                   cr_ChecksumType checksum_type,
                                   cr_CompressionType record_compression,
                                   GError **err)
{
    const char *suffix;
    gchar *path, *cpath;
    gchar *clocation_real, *clocation_href;
    gchar *checksum, *cchecksum;
    int readed;
    char buf[BUFFER_SIZE];
    CR_FILE *cw_plain;
    CR_FILE *cw_compressed;
    gint64 gf_size = -1, cgf_size = -1;
    gint64 gf_time = -1, cgf_time = -1;
    struct stat gf_stat, cgf_stat;
    const char *checksum_str = cr_checksum_name_str(checksum_type);
    GError *tmp_err = NULL;

    assert(record);
    assert(crecord);
    assert(!err || *err == NULL);

    if (!(record->location_real) || !strlen(record->location_real)) {
        g_set_error(err, CR_REPOMD_RECORD_ERROR, CRE_BADARG,
                    "Empty locations in repomd record object");
        return CRE_BADARG;
    }

    if (!g_file_test(record->location_real, G_FILE_TEST_IS_REGULAR)) {
        // File doesn't exists
        g_warning("%s: File %s doesn't exists", __func__, record->location_real);
        g_set_error(err, CR_REPOMD_RECORD_ERROR, CRE_NOFILE,
                    "File %s doesn't exists or not a regular file",
                    record->location_real);
        return CRE_NOFILE;;
    }

    // Paths

    suffix = cr_compression_suffix(record_compression);

    clocation_real = g_strconcat(record->location_real, suffix, NULL);
    clocation_href = g_strconcat(record->location_href, suffix, NULL);
    crecord->location_real = g_string_chunk_insert(crecord->chunk,
                                                   clocation_real);
    crecord->location_href = g_string_chunk_insert(crecord->chunk,
                                                   clocation_href);
    g_free(clocation_real);
    g_free(clocation_href);

    path  = record->location_real;
    cpath = crecord->location_real;


    // Compress file + get size of non compressed file

    cw_plain = cr_open(path,
                       CR_CW_MODE_READ,
                       CR_CW_NO_COMPRESSION,
                       &tmp_err);
    if (!cw_plain) {
        int code = tmp_err->code;
        g_propagate_prefixed_error(err, tmp_err, "Cannot open %s: ", path);
        return code;
    }

    cw_compressed = cr_open(cpath,
                            CR_CW_MODE_WRITE,
                            record_compression,
                            &tmp_err);
    if (!cw_compressed) {
        int code = tmp_err->code;
        g_propagate_prefixed_error(err, tmp_err, "Cannot open %s: ", cpath);
        return code;
    }

    while ((readed = cr_read(cw_plain, buf, BUFFER_SIZE, &tmp_err)) > 0) {
        cr_write(cw_compressed, buf, (unsigned int) readed, &tmp_err);
        if (tmp_err)
            break;
    }

    cr_close(cw_plain, NULL);

    if (tmp_err) {
        int code = tmp_err->code;
        cr_close(cw_compressed, NULL);
        g_debug("%s: Error while repomd record compression: %s", __func__,
                tmp_err->message);
        g_propagate_prefixed_error(err, tmp_err,
                "Error while compression %s -> %s:", path, cpath);
        return code;
    }

    cr_close(cw_compressed, &tmp_err);
    if (tmp_err) {
        int code = tmp_err->code;
        g_propagate_prefixed_error(err, tmp_err,
                "Error while closing %s: ", path);
        return code;
    }


    // Compute checksums

    checksum  = cr_checksum_file(path, checksum_type, &tmp_err);
    if (tmp_err) {
        int code = tmp_err->code;
        g_propagate_prefixed_error(err, tmp_err,
                                   "Error while checksum calculation:");
        return code;
    }

    cchecksum = cr_checksum_file(cpath, checksum_type, &tmp_err);
    if (tmp_err) {
        int code = tmp_err->code;
        g_propagate_prefixed_error(err, tmp_err,
                                   "Error while checksum calculation:");
        return code;
    }


    // Get stats

    if (stat(path, &gf_stat)) {
        g_debug("%s: Error while stat() on %s", __func__, path);
        g_set_error(err, CR_REPOMD_RECORD_ERROR, CRE_IO,
                    "Cannot stat %s", path);
        return CRE_IO;
    } else {
        gf_size = gf_stat.st_size;
        gf_time = gf_stat.st_mtime;
    }

    if (stat(cpath, &cgf_stat)) {
        g_debug("%s: Error while stat() on %s", __func__, cpath);
        g_set_error(err, CR_REPOMD_RECORD_ERROR, CRE_IO,
                    "Cannot stat %s", cpath);
        return CRE_IO;
    } else {
        cgf_size = cgf_stat.st_size;
        cgf_time = cgf_stat.st_mtime;
    }


    // Results

    record->checksum = g_string_chunk_insert(record->chunk, checksum);
    record->checksum_type = g_string_chunk_insert(record->chunk, checksum_str);
    record->checksum_open = NULL;
    record->checksum_open_type = NULL;
    record->timestamp = gf_time;
    record->size = gf_size;
    record->size_open = -1;

    crecord->checksum = g_string_chunk_insert(crecord->chunk, cchecksum);
    crecord->checksum_type = g_string_chunk_insert(crecord->chunk, checksum_str);
    crecord->checksum_open = g_string_chunk_insert(record->chunk, checksum);
    crecord->checksum_open_type = g_string_chunk_insert(record->chunk, checksum_str);
    crecord->timestamp = cgf_time;
    crecord->size = cgf_size;
    crecord->size_open = gf_size;

    g_free(checksum);
    g_free(cchecksum);

    return CRE_OK;
}
Ejemplo n.º 7
0
int
cr_repomd_record_fill(cr_RepomdRecord *md,
                      cr_ChecksumType checksum_type,
                      GError **err)
{
    const char *checksum_str;
    cr_ChecksumType checksum_t;
    gchar *path;
    GError *tmp_err = NULL;

    assert(md);
    assert(!err || *err == NULL);

    if (!(md->location_real) || !strlen(md->location_real)) {
        g_set_error(err, CR_REPOMD_RECORD_ERROR, CRE_BADARG,
                    "Empty locations in repomd record object.");
        return CRE_BADARG;
    }

    path = md->location_real;

    checksum_str = cr_checksum_name_str(checksum_type);
    checksum_t = checksum_type;

    if (!g_file_test(path, G_FILE_TEST_IS_REGULAR)) {
        // File doesn't exists
        g_warning("%s: File %s doesn't exists", __func__, path);
        g_set_error(err, CR_REPOMD_RECORD_ERROR, CRE_NOFILE,
                    "File %s doesn't exists or not a regular file", path);
        return CRE_NOFILE;
    }


    // Compute checksum of compressed file

    if (!md->checksum_type || !md->checksum) {
        gchar *chksum;

        chksum = cr_checksum_file(path, checksum_t, &tmp_err);
        if (tmp_err) {
            int code = tmp_err->code;
            g_propagate_prefixed_error(err, tmp_err,
                "Error while checksum calculation of %s:", path);
            return code;
        }

        md->checksum_type = g_string_chunk_insert(md->chunk, checksum_str);
        md->checksum = g_string_chunk_insert(md->chunk, chksum);
        g_free(chksum);
    }


    // Compute checksum of non compressed content and its size

    if (!md->checksum_open_type || !md->checksum_open || !md->size_open) {
        cr_CompressionType com_type = cr_detect_compression(path, &tmp_err);
        if (tmp_err) {
            int code = tmp_err->code;
            g_propagate_prefixed_error(err, tmp_err,
                    "Cannot detect compression type of %s: ", path);
            return code;
        }

        if (com_type != CR_CW_UNKNOWN_COMPRESSION &&
            com_type != CR_CW_NO_COMPRESSION)
        {
            // File compressed by supported algorithm
            contentStat *open_stat = NULL;

            open_stat = cr_get_compressed_content_stat(path, checksum_t, &tmp_err);
            if (tmp_err) {
                int code = tmp_err->code;
                g_propagate_prefixed_error(err, tmp_err,
                    "Error while computing stat of compressed content of %s:",
                    path);
                return code;
            }

            md->checksum_open_type = g_string_chunk_insert(md->chunk, checksum_str);
            md->checksum_open = g_string_chunk_insert(md->chunk, open_stat->checksum);
            if (!md->size_open)
                md->size_open = open_stat->size;
            g_free(open_stat->checksum);
            g_free(open_stat);
        } else {
            if (com_type != CR_CW_NO_COMPRESSION) {
                // Unknown compression
                g_warning("%s: File \"%s\" compressed by an unsupported type"
                          " of compression", __func__, path);
            }
            md->checksum_open_type = NULL;
            md->checksum_open = NULL;
            md->size_open = -1;
        }
    }


    // Get timestamp and size of compressed file

    if (!md->timestamp || !md->size) {
        struct stat buf;
        if (!stat(path, &buf)) {
            if (!md->timestamp) {
                md->timestamp = buf.st_mtime;
            }
            if (!md->size) {
                md->size = buf.st_size;
            }
        } else {
            g_warning("%s: Stat on file \"%s\" failed", __func__, path);
            g_set_error(err, CR_REPOMD_RECORD_ERROR, CRE_STAT,
                        "Stat() on %s failed: %s", path, strerror(errno));
            return CRE_STAT;
        }
    }


    // Set db version

    if (!md->db_ver)
        md->db_ver = DEFAULT_DATABASE_VERSION;

    return CRE_OK;
}