示例#1
0
文件: yum.c 项目: akozumpl/librepo
int
lr_yum_download_repo(lr_Handle handle, lr_YumRepo repo, lr_YumRepoMd repomd)
{
    int ret = LRE_OK;
    char *destdir;  /* Destination dir */
    lr_CurlTargetList targets = lr_curltargetlist_new();

    destdir = handle->destdir;
    DEBUGASSERT(destdir);
    DEBUGASSERT(strlen(destdir));

    for (int x = 0; x < repomd->nor; x++) {
        int fd;
        char *path;
        lr_CurlTarget target;
        lr_YumRepoMdRecord record = repomd->records[x];

        if (!lr_yum_repomd_record_enabled(handle, record->type))
            continue;

        path = lr_pathconcat(destdir, record->location_href, NULL);
        fd = open(path, O_CREAT|O_TRUNC|O_RDWR, 0660);
        if (fd < 0) {
            DPRINTF("%s: Cannot create/open %s (%s)\n",
                    __func__, path, strerror(errno));
            lr_free(path);
            return LRE_IO;
        }

        target = lr_curltarget_new();
        target->path = lr_strdup(record->location_href);
        target->fd = fd;
        target->checksum_type = lr_checksum_type(record->checksum_type);
        target->checksum = lr_strdup(record->checksum);
        lr_curltargetlist_append(targets, target);

        /* Becouse path may already exists in repo (while update) */
        lr_yum_repo_update(repo, record->type, path);
        lr_free(path);
    }

    if (lr_curltargetlist_len(targets) > 0)
        ret = lr_curl_multi_download(handle, targets);

    lr_curltargetlist_free(targets);
    return ret;
}
示例#2
0
文件: yum.c 项目: akozumpl/librepo
int
lr_yum_download_repomd(lr_Handle handle,
                       lr_Metalink metalink,
                       int fd)
{
    int rc = LRE_OK;
    lr_ChecksumType checksum_type = LR_CHECKSUM_UNKNOWN;
    char *checksum = NULL;


    DPRINTF("%s: Downloading repomd.xml via mirrorlist\n", __func__);

    if (metalink && (handle->checks & LR_CHECK_CHECKSUM)) {
        /* Select the best checksum type */
        for (int x = 0; x < metalink->noh; x++) {
            lr_ChecksumType mtype;
            lr_MetalinkHash mhash = metalink->hashes[x];

            if (!mhash->type || !mhash->value)
                continue;

            mtype = lr_checksum_type(mhash->type);
            if (mtype != LR_CHECKSUM_UNKNOWN && mtype > checksum_type) {
                checksum_type = mtype;
                checksum = mhash->value;
            }
        }

        DPRINTF("%s: selected repomd.xml checksum to check: (%s) %s\n",
                __func__, lr_checksum_type_to_str(checksum_type), checksum);
    }

    rc = lr_curl_single_mirrored_download(handle,
                                          "repodata/repomd.xml",
                                          fd,
                                          checksum_type,
                                          checksum);

    if (rc != LRE_OK) {
        /* Download of repomd.xml was not successful */
        DPRINTF("%s: repomd.xml download was unsuccessful\n", __func__);
        return rc;
    }

    return LRE_OK;
}
示例#3
0
文件: yum.c 项目: akozumpl/librepo
int
lr_yum_check_checksum_of_md_record(lr_YumRepoMdRecord rec, char *path)
{
    int ret, fd;
    char *expected_checksum;
    lr_ChecksumType checksum_type;

    if (!rec || !path)
        return LRE_OK;

    expected_checksum = rec->checksum;
    checksum_type = lr_checksum_type(rec->checksum_type);

    DPRINTF("%s: Checking checksum of %s (expected: %s [%s])\n",
                       __func__, path, expected_checksum, rec->checksum_type);

    if (!expected_checksum) {
        DPRINTF("%s: No checksum in repomd\n", __func__);
        return LRE_OK;  /* Empty checksum - suppose it's ok */
    }

    if (checksum_type == LR_CHECKSUM_UNKNOWN) {
        DPRINTF("%s: Unknown checksum: %s\n", __func__, rec->checksum_type);
        return LRE_UNKNOWNCHECKSUM;
    }

    fd = open(path, O_RDONLY);
    if (fd < 0) {
        DPRINTF("%s: Cannot open %s\n", __func__, path);
        return LRE_IO;
    }

    ret = lr_checksum_fd_cmp(checksum_type, fd, expected_checksum);

    close(fd);

    if (ret) {
        DPRINTF("%s: Checksum check - Failed\n", __func__);
        return LRE_BADCHECKSUM;
    }

    DPRINTF("%s: Checksum check - Passed\n", __func__);

    return LRE_OK;
}
示例#4
0
文件: yum.c 项目: sourcejedi/librepo
static gboolean
lr_yum_check_checksum_of_md_record(LrYumRepoMdRecord *rec,
                                   const char *path,
                                   GError **err)
{
    int fd;
    char *expected_checksum;
    LrChecksumType checksum_type;
    gboolean ret, matches;
    GError *tmp_err = NULL;

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

    if (!rec || !path)
        return TRUE;

    expected_checksum = rec->checksum;
    checksum_type = lr_checksum_type(rec->checksum_type);

    g_debug("%s: Checking checksum of %s (expected: %s [%s])",
                       __func__, path, expected_checksum, rec->checksum_type);

    if (!expected_checksum) {
        // Empty checksum - suppose it's ok
        g_debug("%s: No checksum in repomd", __func__);
        return TRUE;
    }

    if (checksum_type == LR_CHECKSUM_UNKNOWN) {
        g_debug("%s: Unknown checksum: %s", __func__, rec->checksum_type);
        g_set_error(err, LR_YUM_ERROR, LRE_UNKNOWNCHECKSUM,
                    "Unknown checksum type \"%s\" for %s",
                    rec->checksum_type, path);
        return FALSE;
    }

    fd = open(path, O_RDONLY);
    if (fd < 0) {
        g_debug("%s: Cannot open %s", __func__, path);
        g_set_error(err, LR_YUM_ERROR, LRE_IO,
                    "Cannot open %s: %s", path, g_strerror(errno));
        return FALSE;
    }

    ret = lr_checksum_fd_cmp(checksum_type,
                             fd,
                             expected_checksum,
                             1,
                             &matches,
                             &tmp_err);

    close(fd);

    assert(ret || tmp_err);

    if (!ret) {
        // Checksum calculation error
        g_debug("%s: Checksum check %s - Error: %s",
                __func__, path, tmp_err->message);
        g_propagate_prefixed_error(err, tmp_err,
                                   "Checksum error %s: ", path);
        return FALSE;
    } else if (!matches) {
        g_debug("%s: Checksum check %s - Mismatch", __func__, path);
        g_set_error(err, LR_YUM_ERROR, LRE_BADCHECKSUM,
                    "Checksum mismatch %s", path);
        return FALSE;
    }

    g_debug("%s: Checksum check - Passed", __func__);

    return TRUE;
}
示例#5
0
文件: yum.c 项目: sourcejedi/librepo
static gboolean
lr_yum_download_repo(LrHandle *handle,
                     LrYumRepo *repo,
                     LrYumRepoMd *repomd,
                     GError **err)
{
    gboolean ret = TRUE;
    char *destdir;  /* Destination dir */
    GSList *targets = NULL;
    GSList *cbdata_list = NULL;
    GError *tmp_err = NULL;

    destdir = handle->destdir;
    assert(destdir);
    assert(strlen(destdir));
    assert(!err || *err == NULL);

    for (GSList *elem = repomd->records; elem; elem = g_slist_next(elem)) {
        int fd;
        char *path;
        LrDownloadTarget *target;
        LrYumRepoMdRecord *record = elem->data;
        CbData *cbdata = NULL;

        assert(record);

        if (!lr_yum_repomd_record_enabled(handle, record->type))
            continue;

        path = lr_pathconcat(destdir, record->location_href, NULL);
        fd = open(path, O_CREAT|O_TRUNC|O_RDWR, 0666);
        if (fd < 0) {
            g_debug("%s: Cannot create/open %s (%s)",
                    __func__, path, g_strerror(errno));
            g_set_error(err, LR_YUM_ERROR, LRE_IO,
                        "Cannot create/open %s: %s", path, g_strerror(errno));
            lr_free(path);
            g_slist_free_full(targets, (GDestroyNotify) lr_downloadtarget_free);
            return FALSE;
        }

        GSList *checksums = NULL;
        if (handle->checks & LR_CHECK_CHECKSUM) {
            // Select proper checksum type only if checksum check is enabled
            LrDownloadTargetChecksum *checksum;
            checksum = lr_downloadtargetchecksum_new(
                                    lr_checksum_type(record->checksum_type),
                                    record->checksum);
            checksums = g_slist_prepend(checksums, checksum);
        }

        if (handle->user_cb || handle->hmfcb) {
            cbdata = cbdata_new(handle->user_data,
                                handle->user_cb,
                                handle->hmfcb,
                                record->type);
            cbdata_list = g_slist_append(cbdata_list, cbdata);
        }

        target = lr_downloadtarget_new(handle,
                                       record->location_href,
                                       record->location_base,
                                       fd,
                                       NULL,
                                       checksums,
                                       0,
                                       0,
                                       NULL,
                                       cbdata,
                                       NULL,
                                       NULL,
                                       NULL,
                                       0,
                                       0);

        targets = g_slist_append(targets, target);

        /* Because path may already exists in repo (while update) */
        lr_yum_repo_update(repo, record->type, path);
        lr_free(path);
    }

    if (!targets)
        return TRUE;

    ret = lr_download_single_cb(targets,
                                FALSE,
                                (cbdata_list) ? progresscb : NULL,
                                (cbdata_list) ? hmfcb : NULL,
                                &tmp_err);

    // Error handling

    assert((ret && !tmp_err) || (!ret && tmp_err));

    if (tmp_err) {
        g_propagate_prefixed_error(err, tmp_err,
                                   "Downloading error: ");
    } else {
        int code = LRE_OK;
        char *error_summary = NULL;

        for (GSList *elem = targets; elem; elem = g_slist_next(elem)) {
            LrDownloadTarget *target = elem->data;
            if (target->rcode != LRE_OK) {
                if (code == LRE_OK) {
                    // First failed download target found
                    code = target->rcode;
                    error_summary = g_strconcat(target->path,
                                                " - ",
                                                target->err,
                                                NULL);
                } else {
                    error_summary = g_strconcat(error_summary,
                                                "; ",
                                                target->path,
                                                " - ",
                                                target->err,
                                                NULL);
                }
            }

            close(target->fd);
        }

        if (code != LRE_OK) {
            // At least one target failed
            ret = FALSE;
            g_set_error(err, LR_DOWNLOADER_ERROR, code,
                        "Downloading error(s): %s", error_summary);
            g_free(error_summary);
        }
    }

    g_slist_free_full(cbdata_list, (GDestroyNotify)cbdata_free);
    g_slist_free_full(targets, (GDestroyNotify)lr_downloadtarget_free);

    return ret;
}