Example #1
0
LIB_EXPORT rc_t CC aspera_get(
    const char *ascp_bin, const char *private_file, const char *aSrc,
    const char *dest, AscpOptions *opt)
{
    char path[PATH_MAX] = "";
    AscpOptions dummy;
    bool status = false;
    int64_t prev = -1;
    int attempt = 0;
    KDirectory *dir = NULL;
    TQuitting *quitting = NULL;
    const char *src = aSrc;
    rc_t rc = KDirectoryNativeDir(&dir);
    if (rc != 0) {
        return rc;
    }
    if (ascp_bin == NULL || private_file == NULL ||
        src == NULL || dest == NULL)
    {
        return RC(rcNS, rcFile, rcCopying, rcParam, rcNull);
    }
    if (opt == NULL) {
        memset(&dummy, 0, sizeof dummy);
        opt = &dummy;
    }

    if (opt->ascp_options == NULL && opt->target_rate[0] == '\0') {
        KConfig *cfg = NULL;
        rc_t rc = KConfigMake(&cfg, NULL);
        DISP_RC(rc, "cannot KConfigMake");
        if (rc == 0) {
            rc = _KConfigGetAscpRate(cfg,
                opt->target_rate, sizeof opt->target_rate);
            DISP_RC(rc, "cannot get aspera max rate");
        }
        RELEASE(KConfig, cfg);
    }

    sStatus = status = opt->status;
    quitting = opt->quitting;

    {
        /* remove trailing #... or ?... from src path:
           it could come from Revolver */
        size_t s = string_size(aSrc);
        const char *n = string_chr(aSrc, s, '#');
        const char *q = string_chr(aSrc, s, '?');
        if (q != NULL && (n == NULL || q < n)) {
            n = q;
        }
        if (n != NULL) {
            if (n - aSrc + 1 > sizeof path) {
                return RC(rcNS, rcFile, rcCopying, rcBuffer, rcInsufficient);
            }
            else {
#if _DEBUGGING
                size_t s =
#endif
                    string_copy(path, sizeof path, aSrc, n - aSrc);
                assert(s <= sizeof path);
                src = path;
            }
        }
    }

    while (true) {
        rc = run_ascp(ascp_bin, private_file, src, dest, opt);
        if (rc == 0) {
            if (status) {
                STSMSG(STS_DBG, ("ascp finished with success"));
            }
            break;
        }
        else if (rc == SILENT_RC(rcExe,
            rcProcess, rcExecuting, rcMemory, rcExhausted))
        {
            if (status) {
                STSMSG(STS_DBG, ("ascp failed: %R", rc));
            }
            break;
        }
        else {
            rc_t rc2 = 0;
            uint64_t size = 0;
            if (quitting != NULL) {
                rc2 = quitting();
                if (rc2 != 0) {
                    break;
                }
            }
            if (status) {
                STSMSG(STS_DBG, ("ascp failed: %R", rc));
            }
            rc2 = KDirectoryFileSize(dir, &size, "%s", dest);
            if (rc2 ==
                SILENT_RC(rcFS, rcDirectory, rcAccessing, rcPath, rcNotFound))
            {
                if (prev < 0) {
                    if (status) {
                        STSMSG(0, ("fasp download failed. "
                            "File not found. Retrying..."));
                    }
                    prev = 0;
                }
                else {
                    if (status) {
                        STSMSG(0, ("fasp download failed. File not found."));
                    }
                    break;
                }
            }
            else if (rc2 != 0 || (int64_t)size < prev) {
                if (status) {
                    STSMSG(0, ("fasp download failed. KDirectoryFileSize "
                        "after ascp run: rc = %ld, size = %ld", rc, size));
                }
                break;
            }
            else if ((int64_t)size > prev) {
                if (status) {
                    STSMSG(STS_INFO, ("  fasp download failed. %ld bytes "
                        "received so far. Retrying...", size));
                }
                attempt = 0;
                prev = size;
            }
            else {
                if (attempt++ > 3) {
                    break;
                }
                if (status) {
                    STSMSG(STS_INFO, ("  fasp download failed. %ld bytes "
                        "received so far. Retrying %d...", size, attempt));
                }
            }
        }
    }

    RELEASE(KDirectory, dir);
    return rc;
}
Example #2
0
LIB_EXPORT rc_t CC aspera_get(
    const char *ascp_bin, const char *private_file, const char *src,
    const char *dest, AscpOptions *opt)
{
    AscpOptions dummy;
    bool status = false;
    uint64_t prev = 0;
    int attempt = 0;
    KDirectory *dir = NULL;
    TQuitting *quitting = NULL;
    rc_t rc = KDirectoryNativeDir(&dir);
    if (rc != 0) {
        return rc;
    }
    if (ascp_bin == NULL || private_file == NULL ||
        src == NULL || dest == NULL)
    {
        return RC(rcNS, rcFile, rcCopying, rcParam, rcNull);
    }
    if (opt == NULL) {
        memset(&dummy, 0, sizeof dummy);
        opt = &dummy;
    }

    if (opt->target_rate == NULL) {
        KConfig *cfg = NULL;
        rc_t rc = KConfigMake(&cfg, NULL);
        DISP_RC(rc, "cannot KConfigMake");
        if (rc == 0) {
            rc = _KConfigGetAscpRate(cfg, &opt->target_rate);
            DISP_RC(rc, "cannot get aspera max rate");
        }
        RELEASE(KConfig, cfg);
    }

    sStatus = status = opt->status;
    quitting = opt->quitting;

    while (true) {
        rc = run_ascp(ascp_bin, private_file, src, dest, opt);
        if (rc == 0) {
            if (status) {
                STSMSG(STS_DBG, ("ascp finished with success"));
            }
            break;
        }
        else if (rc == SILENT_RC(rcExe,
            rcProcess, rcExecuting, rcMemory, rcExhausted))
        {
            if (status) {
                STSMSG(STS_DBG, ("ascp failed: %R", rc));
            }
            break;
        }
        else {
            rc_t rc = 0;
            uint64_t size = 0;
            if (quitting != NULL) {
                rc = quitting();
                if (rc != 0) {
                    break;
                }
            }
            if (status) {
                STSMSG(STS_DBG, ("ascp failed: %R", rc));
            }
            rc = KDirectoryFileSize(dir, &size, dest);
            if (rc != 0 || size < prev) {
            if (status) {
STSMSG(0, ("KDirectoryFileSize after ascp run: "
"rc = %ld, size = %ld", rc, size));
            }
                break;
            }
            else if (size > prev) {
                if (status) {
                    STSMSG(STS_INFO, ("  fasp download failed. %ld bytes "
                        "received so far. Retrying...", size));
                }
                attempt = 0;
                prev = size;
            } else {
                if (attempt++ > 3) {
                    break;
                }
                if (status) {
                    STSMSG(STS_INFO, ("  fasp download failed. %ld bytes "
                        "received so far. Retrying %d...", size, attempt));
                }
            }
        }
    }
    RELEASE(KDirectory, dir);
    return rc;
}