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; }
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; }