diff --git a/headers/private/package/FetchFileJob.h b/headers/private/package/FetchFileJob.h index f43f8a23f2..fbaa656e80 100644 --- a/headers/private/package/FetchFileJob.h +++ b/headers/private/package/FetchFileJob.h @@ -1,5 +1,6 @@ /* * Copyright 2011, Oliver Tappe + * Copyright 2013, Rene Gollent * Distributed under the terms of the MIT License. */ #ifndef _PACKAGE__PRIVATE__FETCH_FILE_JOB_H_ @@ -7,6 +8,7 @@ #include +#include #include #include @@ -31,9 +33,19 @@ protected: virtual status_t Execute(); virtual void Cleanup(status_t jobResult); +private: + // libcurl callbacks + static int _ProgressCallback(void *clientp, + double dltotal, double dlnow, + double ultotal, double ulnow); + + static size_t _WriteCallback(void *buffer, size_t size, + size_t nmemb, void *userp); + private: BString fFileURL; BEntry fTargetEntry; + BFile fTargetFile; }; diff --git a/src/build/libpackage/Jamfile b/src/build/libpackage/Jamfile index bef49e4465..d92f41f0fa 100644 --- a/src/build/libpackage/Jamfile +++ b/src/build/libpackage/Jamfile @@ -137,8 +137,7 @@ BuildPlatformSharedLibrary libpackage_build.so SolverRepository.cpp SolverResult.cpp : - libshared_build.a $(HOST_LIBBE) z $(HOST_LIBSTDC++) + libshared_build.a $(HOST_LIBBE) curl z $(HOST_LIBSTDC++) ; - HaikuSubInclude solver ; diff --git a/src/kits/package/FetchFileJob.cpp b/src/kits/package/FetchFileJob.cpp index afbcc5c6cc..598f004c79 100644 --- a/src/kits/package/FetchFileJob.cpp +++ b/src/kits/package/FetchFileJob.cpp @@ -1,15 +1,17 @@ /* - * Copyright 2011, Haiku, Inc. All Rights Reserved. + * Copyright 2011-2013, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: * Oliver Tappe + * Rene Gollent */ #include -#include +#include +#include #include #include @@ -25,7 +27,8 @@ FetchFileJob::FetchFileJob(const BContext& context, const BString& title, : inherited(context, title), fFileURL(fileURL), - fTargetEntry(targetEntry) + fTargetEntry(targetEntry), + fTargetFile(&targetEntry, B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY) { } @@ -38,22 +41,76 @@ FetchFileJob::~FetchFileJob() status_t FetchFileJob::Execute() { - BPath targetPath; - status_t result = fTargetEntry.GetPath(&targetPath); + status_t result = fTargetFile.InitCheck(); if (result != B_OK) return result; - // TODO: implement for real, maybe using the "service kit"-GSOC HTTP-stuff? - BString cmd = BString("curl -# -o ") << targetPath.Path() << " " - << fFileURL.String(); + CURL* handle = curl_easy_init(); - int cmdResult = system(cmd.String()); - if (WIFSIGNALED(cmdResult) - && (WTERMSIG(cmdResult) == SIGINT || WTERMSIG(cmdResult) == SIGQUIT)) { - return B_CANCELED; + if (handle == NULL) + return B_NO_MEMORY; + + result = curl_easy_setopt(handle, CURLOPT_NOPROGRESS, 0); + + result = curl_easy_setopt(handle, CURLOPT_PROGRESSFUNCTION, + &_ProgressCallback); + if (result != CURLE_OK) + return B_BAD_VALUE; + + result = curl_easy_setopt(handle, CURLOPT_PROGRESSDATA, this); + if (result != CURLE_OK) + return B_ERROR; + + result = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, + &_WriteCallback); + if (result != CURLE_OK) + return B_ERROR; + + result = curl_easy_setopt(handle, CURLOPT_WRITEDATA, this); + if (result != CURLE_OK) + return B_ERROR; + + result = curl_easy_setopt(handle, CURLOPT_PROGRESSFUNCTION, + &_ProgressCallback); + if (result != CURLE_OK) + return B_ERROR; + + result = curl_easy_setopt(handle, CURLOPT_URL, fFileURL.String()); + if (result != CURLE_OK) + return B_ERROR; + + result = curl_easy_perform(handle); + curl_easy_cleanup(handle); + if (result != CURLE_OK) { + // TODO: map more curl error codes to ours for more + // precise error reporting + return B_ERROR; } - return cmdResult == 0 ? B_OK : B_ERROR; +/* if (WIFSIGNALED(cmdResult) + && (WTERMSIG(cmdResult) == SIGINT || WTERMSIG(cmdResult) == SIGQUIT)) { + return B_CANCELED; + } */ + + return B_OK; +} + + +int +FetchFileJob::_ProgressCallback(void *clientp, double dltotal, double dlnow, + double ultotal, double ulnow) +{ + return 0; +} + + +size_t +FetchFileJob::_WriteCallback(void *buffer, size_t size, size_t nmemb, + void *userp) +{ + FetchFileJob* job = reinterpret_cast(userp); + ssize_t dataWritten = job->fTargetFile.Write(buffer, size * nmemb); + return size_t(dataWritten); } diff --git a/src/kits/package/Jamfile b/src/kits/package/Jamfile index 80e2e10a14..a8acd9cf8f 100644 --- a/src/kits/package/Jamfile +++ b/src/kits/package/Jamfile @@ -63,6 +63,7 @@ HPKG_SOURCES = local architectureObject ; for architectureObject in [ MultiArchSubDirSetup ] { on $(architectureObject) { + UseBuildFeatureHeaders curl ; UseBuildFeatureHeaders zlib ; SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package hpkg ] ; @@ -70,6 +71,8 @@ for architectureObject in [ MultiArchSubDirSetup ] { SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package manager ] ; SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package solver ] ; + Includes [ FGristFiles FetchFileJob.cpp ] + : [ BuildFeatureAttribute curl : headers ] ; Includes [ FGristFiles $(HPKG_SOURCES) ] : [ BuildFeatureAttribute zlib : headers ] ; @@ -130,6 +133,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { : [ MultiArchDefaultGristFiles libshared.a ] be + [ BuildFeatureAttribute curl : library ] [ BuildFeatureAttribute zlib : library ] $(TARGET_LIBSTDC++) ;