Пример #1
0
/**
 * Check parsed arguments and fill some other attributes
 * of option struct accordingly.
 */
static gboolean
check_arguments(SqliterepoCmdOptions *options, GError **err)
{
    // --compress-type
    if (options->compress_type) {
        options->compression_type = cr_compression_type(options->compress_type);
        if (options->compression_type == CR_CW_UNKNOWN_COMPRESSION) {
            g_set_error(err, CREATEREPO_C_ERROR, CRE_ERROR,
                        "Unknown compression type \"%s\"", options->compress_type);
            return FALSE;
        }
    }

    // --checksum
    if (options->chcksum_type) {
        cr_ChecksumType type;
        type = cr_checksum_type(options->chcksum_type);
        if (type == CR_CHECKSUM_UNKNOWN) {
            g_set_error(err, CREATEREPO_C_ERROR, CRE_BADARG,
                        "Unknown/Unsupported checksum type \"%s\"",
                        options->chcksum_type);
            return FALSE;
        }
        options->checksum_type = type;
    }

    // --xz
    if (options->xz_compression)
        options->compression_type = CR_CW_XZ_COMPRESSION;

    return TRUE;
}
static gboolean
check_arguments(RawCmdOptions *options, GError **err)
{
    // --no-compress
    if (options->no_compress) {
        options->compress = FALSE;
        if (options->compress_type) {
            g_warning("Use --compress-type simultaneously with --no-compress "
                      "doesn't make a sense");
        }
    }

    // --compress-type
    if (options->compress_type
        && cr_compression_type(options->compress_type) == \
           CR_CW_UNKNOWN_COMPRESSION)
    {
        g_set_error(err, ERR_DOMAIN, CRE_ERROR,
                    "Unknown compression type \"%s\"", options->compress_type);
        return FALSE;
    }

    // -s/--checksum
    if (options->checksum
        && cr_checksum_type(options->checksum) == CR_CHECKSUM_UNKNOWN)
    {
        g_set_error(err, ERR_DOMAIN, CRE_ERROR,
                    "Unknown checksum type \"%s\"", options->checksum);
        return FALSE;
    }

    // --unique_md_filenames && --simple_md_filenames
    if (options->simple_md_filenames) {
        options->unique_md_filenames = FALSE;
    }

    // -f/--batchfile
    if (options->batchfile
        && !g_file_test(options->batchfile, G_FILE_TEST_IS_REGULAR)) {
        g_set_error(err, ERR_DOMAIN, CRE_ERROR,
                    "File \"%s\" doesn't exist", options->batchfile);
        return FALSE;
    }

    // Zchunk options
    if (options->zck_dict_dir && !options->zck) {
        g_set_error(err, ERR_DOMAIN, CRE_ERROR,
                    "Cannot use --zck-dict-dir without setting --zck");
        return FALSE;
    }
    if (options->zck_dict_dir)
        options->zck_dict_dir = cr_normalize_dir_path(options->zck_dict_dir);

    return TRUE;
}
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;
}
Пример #4
0
PyObject *
py_checksum_type(PyObject *self, PyObject *args)
{
    char *type;

    CR_UNUSED(self);

    if (!PyArg_ParseTuple(args, "s:py_checksum_type", &type))
        return NULL;

    return PyLong_FromLong((long) cr_checksum_type(type));
}
Пример #5
0
static gboolean
check_arguments(RawCmdOptions *options, GError **err)
{
    // --no-compress
    if (options->no_compress) {
        options->compress = FALSE;
        if (options->compress_type) {
            g_warning("Use --compress-type simultaneously with --no-compress "
                      "doesn't make a sense");
        }
    }

    // --compress-type
    if (options->compress_type
        && cr_compression_type(options->compress_type) == \
           CR_CW_UNKNOWN_COMPRESSION)
    {
        g_set_error(err, CR_MODIFYREPO_ERROR, CRE_ERROR,
                    "Unknown compression type \"%s\"", options->compress_type);
        return FALSE;
    }

    // -s/--checksum
    if (options->checksum
        && cr_checksum_type(options->checksum) == CR_CHECKSUM_UNKNOWN)
    {
        g_set_error(err, CR_MODIFYREPO_ERROR, CRE_ERROR,
                    "Unknown checksum type \"%s\"", options->checksum);
        return FALSE;
    }

    // --unique_md_filenames && --simple_md_filenames
    if (options->simple_md_filenames) {
        options->unique_md_filenames = FALSE;
    }

    // -f/--batchfile
    if (options->batchfile
        && !g_file_test(options->batchfile, G_FILE_TEST_IS_REGULAR)) {
        g_set_error(err, CR_MODIFYREPO_ERROR, CRE_ERROR,
                    "File \"%s\" doesn't exist", options->batchfile);
        return FALSE;
    }

    return TRUE;
}
Пример #6
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;
}
gboolean
check_arguments(struct CmdOptions *options,
                const char *input_dir,
                GError **err)
{
    assert(!err || *err == NULL);

    // Check outputdir
    if (options->outputdir && !g_file_test(options->outputdir, G_FILE_TEST_EXISTS|G_FILE_TEST_IS_DIR)) {
        g_set_error(err, ERR_DOMAIN, CRE_BADARG,
                    "Specified outputdir \"%s\" doesn't exists",
                    options->outputdir);
        return FALSE;
    }

    // Check workers
    if ((options->workers < 1) || (options->workers > 100)) {
        g_warning("Wrong number of workers - Using 5 workers.");
        options->workers = DEFAULT_WORKERS;
    }

    // Check changelog_limit
    if ((options->changelog_limit < -1)) {
        g_warning("Wrong changelog limit \"%d\" - Using 10", options->changelog_limit);
        options->changelog_limit = DEFAULT_CHANGELOG_LIMIT;
    }

    // Check simple filenames
    if (options->simple_md_filenames) {
        options->unique_md_filenames = FALSE;
    }

    // Check and set checksum type
    if (options->checksum) {
        cr_ChecksumType type;
        type = cr_checksum_type(options->checksum);
        if (type == CR_CHECKSUM_UNKNOWN) {
            g_set_error(err, ERR_DOMAIN, CRE_BADARG,
                        "Unknown/Unsupported checksum type \"%s\"",
                        options->checksum);
            return FALSE;
        }
        options->checksum_type = type;
    }

    // Check and set checksum type for repomd
    if (options->repomd_checksum) {
        cr_ChecksumType type;
        type = cr_checksum_type(options->repomd_checksum);
        if (type == CR_CHECKSUM_UNKNOWN) {
            g_set_error(err, ERR_DOMAIN, CRE_BADARG,
                        "Unknown/Unsupported checksum type \"%s\"",
                        options->repomd_checksum);
            return FALSE;
        }
        options->repomd_checksum_type = type;
    } else {
        options->repomd_checksum_type = options->checksum_type;
    }

    // Check and set compression type
    if (options->compress_type) {
        if (!check_and_set_compression_type(options->compress_type,
                                            &(options->compression_type),
                                            err)) {
            return FALSE;
        }
    }
    //options --xz has priority over compress_type, but not over general_compress_type
    if (options->xz_compression) {
        options->compression_type = CR_CW_XZ_COMPRESSION;
    }

    // Check and set general compression type
    if (options->general_compress_type) {
        if (!check_and_set_compression_type(options->general_compress_type,
                                            &(options->general_compression_type),
                                            err)) {
            return FALSE;
        }
    }

    int x;

    // Process exclude glob masks
    x = 0;
    while (options->excludes && options->excludes[x] != NULL) {
        GPatternSpec *pattern = g_pattern_spec_new(options->excludes[x]);
        options->exclude_masks = g_slist_prepend(options->exclude_masks,
                                                 (gpointer) pattern);
        x++;
    }

    // Process includepkgs
    x = 0;
    while (options->includepkg && options->includepkg[x] != NULL) {
        options->include_pkgs = g_slist_prepend(options->include_pkgs,
                                  (gpointer) g_strdup(options->includepkg[x]));
        x++;
    }

    // Check groupfile
    options->groupfile_fullpath = NULL;
    if (options->groupfile) {
        gboolean remote = FALSE;

        if (g_str_has_prefix(options->groupfile, "/")) {
            // Absolute local path
            options->groupfile_fullpath = g_strdup(options->groupfile);
        } else if (strstr(options->groupfile, "://")) {
            // Remote groupfile
            remote = TRUE;
            options->groupfile_fullpath = g_strdup(options->groupfile);
        } else {
            // Relative path (from intput_dir)
            options->groupfile_fullpath = g_strconcat(input_dir,
                                                      options->groupfile,
                                                      NULL);
        }

        if (!remote && !g_file_test(options->groupfile_fullpath, G_FILE_TEST_IS_REGULAR)) {
            g_set_error(err, ERR_DOMAIN, CRE_BADARG,
                        "groupfile %s doesn't exists",
                        options->groupfile_fullpath);
            return FALSE;
        }
    }

    // Process pkglist file
    if (options->pkglist) {
        if (!g_file_test(options->pkglist, G_FILE_TEST_IS_REGULAR)) {
            g_set_error(err, ERR_DOMAIN, CRE_BADARG,
                        "pkglist file \"%s\" doesn't exists", options->pkglist);
            return FALSE;
        } else {
            char *content = NULL;
            GError *tmp_err = NULL;
            if (!g_file_get_contents(options->pkglist, &content, NULL, &tmp_err)) {
                g_warning("Error while reading pkglist file: %s", tmp_err->message);
                g_error_free(tmp_err);
                g_free(content);
            } else {
                x = 0;
                char **pkgs = g_strsplit(content, "\n", 0);
                while (pkgs && pkgs[x] != NULL) {
                    if (strlen(pkgs[x])) {
                        options->include_pkgs = g_slist_prepend(options->include_pkgs,
                                                 (gpointer) g_strdup(pkgs[x]));
                    }
                    x++;
                }

                g_strfreev(pkgs);
                g_free(content);
            }
        }
    }

    // Process update_md_paths
    if (options->update_md_paths && !options->update)
        g_warning("Usage of --update-md-path without --update has no effect!");

    x = 0;
    while (options->update_md_paths && options->update_md_paths[x] != NULL) {
        char *path = options->update_md_paths[x];
        options->l_update_md_paths = g_slist_prepend(options->l_update_md_paths,
                                                     (gpointer) path);
        x++;
    }

    // Check keep-all-metadata
    if (options->keep_all_metadata && !options->update) {
        g_warning("--keep-all-metadata has no effect (--update is not used)");
    }

    // Process --distro tags
    x = 0;
    while (options->distro_tags && options->distro_tags[x]) {
        if (!strchr(options->distro_tags[x], ',')) {
            options->distro_cpeids = g_slist_append(options->distro_cpeids,
                                                    NULL);
            options->distro_values = g_slist_append(options->distro_values,
                                        g_strdup(options->distro_tags[x]));
            x++;
            continue;
        }

        gchar **items = g_strsplit(options->distro_tags[x++], ",", 2);
        if (!items) continue;
        if (!items[0] || !items[1] || items[1][0] == '\0') {
            g_strfreev(items);
            continue;
        }

        if (items[0][0] != '\0')
            options->distro_cpeids = g_slist_append(options->distro_cpeids,
                                                    g_strdup(items[0]));
        else
            options->distro_cpeids = g_slist_append(options->distro_cpeids,
                                                    NULL);
        options->distro_values = g_slist_append(options->distro_values,
                                                g_strdup(items[1]));
        g_strfreev(items);
    }

    // Check retain-old-md-by-age
    if (options->retain_old_md_by_age) {
        if (options->retain_old) {
            g_set_error(err, ERR_DOMAIN, CRE_BADARG,
                        "--retain-old-md-by-age cannot be combined "
                        "with --retain-old-md");
            return FALSE;
        }

        // Parse argument
        if (!parse_period_of_time(options->retain_old_md_by_age,
                                  &options->md_max_age,
                                  err))
            return FALSE;
    }

    // check if --revision is numeric, when --set-timestamp-to-revision is given
    if (options->set_timestamp_to_revision) {
        char *endptr;
        gint64 revision = strtoll(options->revision, &endptr, 0);
        if (endptr == options->revision || *endptr != '\0') {
            g_set_error(err, ERR_DOMAIN, CRE_BADARG,
                    "--set-timestamp-to-revision require numeric value for --revision");
            return FALSE;
        }
        if ((errno == ERANGE && revision == LLONG_MAX) || revision < 0) {
            g_set_error(err, ERR_DOMAIN, CRE_BADARG,
                    "--revision value out of range");
            return FALSE;
        }
    }

    // Check oldpackagedirs
    x = 0;
    while (options->oldpackagedirs && options->oldpackagedirs[x]) {
        char *path = options->oldpackagedirs[x];
        options->oldpackagedirs_paths = g_slist_prepend(
                                            options->oldpackagedirs_paths,
                                            (gpointer) path);
        x++;
    }

    // Check cut_dirs
    if (options->cut_dirs < 0) {
        g_set_error(err, ERR_DOMAIN, CRE_BADARG,
                    "--cur-dirs value must be possitive integer");
        return FALSE;
    }

    // Zchunk options
    if (options->zck_dict_dir && !options->zck_compression) {
        g_set_error(err, ERR_DOMAIN, CRE_BADARG,
                    "Cannot use --zck-dict-dir without setting --zck");
        return FALSE;
    }
    if (options->zck_dict_dir)
        options->zck_dict_dir = cr_normalize_dir_path(options->zck_dict_dir);

    return TRUE;
}