bool CTextureCleanupJob::DoWork() { CTextureDatabase db; if (db.Open()) { std::string path; std::string fn; std::string prevPath = ""; std::vector<std::string> pathContent; XFILE::CSpecialProtocolDirectory thumbDir; CFileItemList files; int fileIdx = 0; int totFileDel = 0; int totDbDel = 0; auto deleteFile = [&]() { std::string todel = files.Get(fileIdx)->GetPath(); CLog::Log(LOGDEBUG, "CTextureCleanupJob: deleting %s", todel.c_str()); XFILE::CFile::Delete(todel); totFileDel++; fileIdx++; }; std::vector<std::pair<int, std::string>> urls = db.GetCachedTextureUrls(); for (const auto &url : urls) { std::string cachedurl = url.second; URIUtils::Split(cachedurl, path, fn); std::string cmpurl = "special://thumbnails/" + cachedurl; if (path != prevPath) { while (fileIdx < files.Size()) deleteFile(); files.Clear(); thumbDir.GetDirectory(CURL("special://thumbnails/" + path), files); files.Sort(SortByPath, SortOrderAscending); prevPath = path; fileIdx = 0; } while (fileIdx < files.Size() && files.Get(fileIdx)->GetPath() < cmpurl) deleteFile(); if (fileIdx < files.Size() && files.Get(fileIdx)->GetPath() == cmpurl) fileIdx++; else { // No file for current entry; delete it CLog::Log(LOGDEBUG, "CTextureCleanupJob: deleting from Db: %d / %s", url.first, cachedurl.c_str()); db.ClearCachedTexture(url.first, cachedurl); totDbDel++; } } while (fileIdx < files.Size()) deleteFile(); CLog::Log(LOGDEBUG, "CTextureCleanupJob: %d thumbnails deleted / %d db entries removed", totFileDel, totDbDel); } return true; }
bool CBufferedRTMPStream::Open(const char* strFile, const std::string &content) { if (!CRTMPStream::Open(strFile, "")) return false; m_cacheUrl = CURL("special://app/cache.bin"); m_fCache.Open(m_cacheUrl); }
CTextureBundleXBT::~CTextureBundleXBT(void) { if (m_XBTFReader != nullptr && m_XBTFReader->IsOpen()) { XFILE::CXbtManager::GetInstance().Release(CURL(m_path)); CLog::Log(LOGDEBUG, "%s - Closed %sbundle", __FUNCTION__, m_themeBundle ? "theme " : ""); } }
TEST_F(TestZipFile, Read) { XFILE::CFile file; char buf[20]; memset(&buf, 0, sizeof(buf)); std::string reffile, strpathinzip; CFileItemList itemlist; reffile = XBMC_REF_FILE_PATH("xbmc/filesystem/test/reffile.txt.zip"); CURL zipUrl = URIUtils::CreateArchivePath("zip", CURL(reffile), ""); ASSERT_TRUE(XFILE::CDirectory::GetDirectory(zipUrl, itemlist, "", XFILE::DIR_FLAG_NO_FILE_DIRS)); EXPECT_GT(itemlist.Size(), 0); EXPECT_FALSE(itemlist[0]->GetPath().empty()); strpathinzip = itemlist[0]->GetPath(); ASSERT_TRUE(file.Open(strpathinzip)); EXPECT_EQ(0, file.GetPosition()); EXPECT_EQ(1616, file.GetLength()); EXPECT_EQ(sizeof(buf), static_cast<size_t>(file.Read(buf, sizeof(buf)))); file.Flush(); EXPECT_EQ(20, file.GetPosition()); EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1)); EXPECT_TRUE(file.ReadString(buf, sizeof(buf))); EXPECT_EQ(39, file.GetPosition()); EXPECT_STREQ("an award-winning fr", buf); EXPECT_EQ(100, file.Seek(100)); EXPECT_EQ(100, file.GetPosition()); EXPECT_EQ(sizeof(buf), static_cast<size_t>(file.Read(buf, sizeof(buf)))); file.Flush(); EXPECT_EQ(120, file.GetPosition()); EXPECT_TRUE(!memcmp("ent hub for digital ", buf, sizeof(buf) - 1)); EXPECT_EQ(220, file.Seek(100, SEEK_CUR)); EXPECT_EQ(220, file.GetPosition()); EXPECT_EQ(sizeof(buf), static_cast<size_t>(file.Read(buf, sizeof(buf)))); file.Flush(); EXPECT_EQ(240, file.GetPosition()); EXPECT_TRUE(!memcmp("rs, XBMC is a non-pr", buf, sizeof(buf) - 1)); EXPECT_EQ(1596, file.Seek(-(int64_t)sizeof(buf), SEEK_END)); EXPECT_EQ(1596, file.GetPosition()); EXPECT_EQ(sizeof(buf), static_cast<size_t>(file.Read(buf, sizeof(buf)))); file.Flush(); EXPECT_EQ(1616, file.GetPosition()); EXPECT_TRUE(!memcmp("multimedia jukebox.\n", buf, sizeof(buf) - 1)); EXPECT_EQ(-1, file.Seek(100, SEEK_CUR)); EXPECT_EQ(1616, file.GetPosition()); EXPECT_EQ(0, file.Seek(0, SEEK_SET)); EXPECT_EQ(sizeof(buf), static_cast<size_t>(file.Read(buf, sizeof(buf)))); file.Flush(); EXPECT_EQ(20, file.GetPosition()); EXPECT_TRUE(!memcmp("About\n-----\nXBMC is ", buf, sizeof(buf) - 1)); EXPECT_EQ(0, file.Seek(0, SEEK_SET)); EXPECT_EQ(-1, file.Seek(-100, SEEK_SET)); file.Close(); }
TEST_F(TestZipFile, Exists) { std::string reffile, strpathinzip; CFileItemList itemlist; reffile = XBMC_REF_FILE_PATH("xbmc/filesystem/test/reffile.txt.zip"); CURL zipUrl = URIUtils::CreateArchivePath("zip", CURL(reffile), ""); ASSERT_TRUE(XFILE::CDirectory::GetDirectory(zipUrl, itemlist, "", XFILE::DIR_FLAG_NO_FILE_DIRS)); strpathinzip = itemlist[0]->GetPath(); EXPECT_TRUE(XFILE::CFile::Exists(strpathinzip)); }
bool CTextureBundleXBT::OpenBundle() { // Find the correct texture file (skin or theme) auto mediaDir = g_graphicsContext.GetMediaDir(); if (mediaDir.empty()) { mediaDir = CSpecialProtocol::TranslatePath( URIUtils::AddFileToFolder("special://home/addons", CServiceBroker::GetSettings().GetString(CSettings::SETTING_LOOKANDFEEL_SKIN))); } if (m_themeBundle) { // if we are the theme bundle, we only load if the user has chosen // a valid theme (or the skin has a default one) std::string theme = CServiceBroker::GetSettings().GetString(CSettings::SETTING_LOOKANDFEEL_SKINTHEME); if (!theme.empty() && !StringUtils::EqualsNoCase(theme, "SKINDEFAULT")) { std::string themeXBT(URIUtils::ReplaceExtension(theme, ".xbt")); m_path = URIUtils::AddFileToFolder(g_graphicsContext.GetMediaDir(), "media", themeXBT); } else { return false; } } else { m_path = URIUtils::AddFileToFolder(g_graphicsContext.GetMediaDir(), "media", "Textures.xbt"); } m_path = CSpecialProtocol::TranslatePathConvertCase(m_path); // Load the texture file if (!XFILE::CXbtManager::GetInstance().GetReader(CURL(m_path), m_XBTFReader)) { return false; } CLog::Log(LOGDEBUG, "%s - Opened bundle %s", __FUNCTION__, m_path.c_str()); m_TimeStamp = m_XBTFReader->GetLastModificationTimestamp(); if (lzo_init() != LZO_E_OK) { return false; } return true; }
void CGUIDialogAudioSubtitleSettings::OnSettingAction(const CSetting *setting) { if (setting == NULL) return; CGUIDialogSettingsManualBase::OnSettingAction(setting); const std::string &settingId = setting->GetId(); if (settingId == SETTING_AUDIO_DSP) { g_windowManager.ActivateWindow(WINDOW_DIALOG_AUDIO_DSP_OSD_SETTINGS); } else if (settingId == SETTING_SUBTITLE_BROWSER) { std::string strPath; if (URIUtils::IsInRAR(g_application.CurrentFileItem().GetPath()) || URIUtils::IsInZIP(g_application.CurrentFileItem().GetPath())) strPath = CURL(g_application.CurrentFileItem().GetPath()).GetHostName(); else strPath = g_application.CurrentFileItem().GetPath(); std::string strMask = ".utf|.utf8|.utf-8|.sub|.srt|.smi|.rt|.txt|.ssa|.aqt|.jss|.ass|.idx|.rar|.zip"; if (g_application.GetCurrentPlayer() == "VideoPlayer") strMask = ".srt|.rar|.zip|.ifo|.smi|.sub|.idx|.ass|.ssa|.txt"; VECSOURCES shares(*CMediaSourceSettings::GetInstance().GetSources("video")); if (CMediaSettings::GetInstance().GetAdditionalSubtitleDirectoryChecked() != -1 && !CServiceBroker::GetSettings().GetString(CSettings::SETTING_SUBTITLES_CUSTOMPATH).empty()) { CMediaSource share; std::vector<std::string> paths; paths.push_back(URIUtils::GetDirectory(strPath)); paths.push_back(CServiceBroker::GetSettings().GetString(CSettings::SETTING_SUBTITLES_CUSTOMPATH)); share.FromNameAndPaths("video",g_localizeStrings.Get(21367),paths); shares.push_back(share); strPath = share.strPath; URIUtils::AddSlashAtEnd(strPath); } if (CGUIDialogFileBrowser::ShowAndGetFile(shares, strMask, g_localizeStrings.Get(293), strPath, false, true)) // "subtitles" { if (URIUtils::HasExtension(strPath, ".sub")) { if (XFILE::CFile::Exists(URIUtils::ReplaceExtension(strPath, ".idx"))) strPath = URIUtils::ReplaceExtension(strPath, ".idx"); } g_application.m_pPlayer->AddSubtitle(strPath); Close(); } } else if (settingId == SETTING_AUDIO_MAKE_DEFAULT) Save(); }
void XBMCHelper::Uninstall() { // Call the unloader. std::string cmd = "/bin/launchctl unload "; cmd += m_launchAgentInstallFile; system(cmd.c_str()); //this also stops the helper, so restart it here again, if not disabled if(m_mode != APPLE_REMOTE_DISABLED) Start(); // Remove the plist file. CURL url = CURL(m_launchAgentInstallFile); XFILE::CFile::Delete(url); }
TEST_F(TestZipFile, Stat) { struct __stat64 buffer; std::string reffile, strpathinzip; CFileItemList itemlist; reffile = XBMC_REF_FILE_PATH("xbmc/filesystem/test/reffile.txt.zip"); CURL zipUrl = URIUtils::CreateArchivePath("zip", CURL(reffile), ""); ASSERT_TRUE(XFILE::CDirectory::GetDirectory(zipUrl, itemlist, "", XFILE::DIR_FLAG_NO_FILE_DIRS)); strpathinzip = itemlist[0]->GetPath(); EXPECT_EQ(0, XFILE::CFile::Stat(strpathinzip, &buffer)); EXPECT_TRUE(buffer.st_mode | _S_IFREG); }
std::string CGUIDialogSubtitleSettings::BrowseForSubtitle() { std::string extras; for (const auto& vfsAddon : CServiceBroker::GetVFSAddonCache().GetAddonInstances()) { if (vfsAddon->ID() == "vfs.rar" || vfsAddon->ID() == "vfs.libarchive") extras += '|' + vfsAddon->GetExtensions(); } std::string strPath; if (URIUtils::IsInRAR(g_application.CurrentFileItem().GetPath()) || URIUtils::IsInZIP(g_application.CurrentFileItem().GetPath())) strPath = CURL(g_application.CurrentFileItem().GetPath()).GetHostName(); else strPath = g_application.CurrentFileItem().GetPath(); std::string strMask = ".utf|.utf8|.utf-8|.sub|.srt|.smi|.rt|.txt|.ssa|.aqt|.jss|.ass|.idx|.zip"; if (g_application.GetCurrentPlayer() == "VideoPlayer") strMask = ".srt|.zip|.ifo|.smi|.sub|.idx|.ass|.ssa|.txt"; strMask += extras; VECSOURCES shares(*CMediaSourceSettings::GetInstance().GetSources("video")); if (CMediaSettings::GetInstance().GetAdditionalSubtitleDirectoryChecked() != -1 && !CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_SUBTITLES_CUSTOMPATH).empty()) { CMediaSource share; std::vector<std::string> paths; paths.push_back(URIUtils::GetDirectory(strPath)); paths.push_back(CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_SUBTITLES_CUSTOMPATH)); share.FromNameAndPaths("video",g_localizeStrings.Get(21367),paths); shares.push_back(share); strPath = share.strPath; URIUtils::AddSlashAtEnd(strPath); } if (CGUIDialogFileBrowser::ShowAndGetFile(shares, strMask, g_localizeStrings.Get(293), strPath, false, true)) // "subtitles" { if (URIUtils::HasExtension(strPath, ".sub")) { if (XFILE::CFile::Exists(URIUtils::ReplaceExtension(strPath, ".idx"))) strPath = URIUtils::ReplaceExtension(strPath, ".idx"); } return strPath; } return ""; }
void XBMCHelper::Install() { // Make sure directory exists. std::string strDir = getenv("HOME"); strDir += "/Library/LaunchAgents"; CURL url = CURL(strDir); XFILE::CDirectory::Create(url); // Load template. std::string plistData = ReadFile(m_launchAgentLocalFile.c_str()); if (plistData != "") { std::string launchd_args; // Replace PATH with path to app. int start = plistData.find("${PATH}"); plistData.replace(start, 7, m_helperFile.c_str(), m_helperFile.length()); // Replace ARG1 with a single argument, additional args // will need ARG2, ARG3 added to plist. launchd_args = "-x"; start = plistData.find("${ARG1}"); plistData.replace(start, 7, launchd_args.c_str(), launchd_args.length()); // Install it. WriteFile(m_launchAgentInstallFile.c_str(), plistData); // Load it if not running already. int pid = GetProcessPid(XBMC_HELPER_PROGRAM); if (pid == -1) { std::string cmd = "/bin/launchctl load "; cmd += m_launchAgentInstallFile; system(cmd.c_str()); } } }
std::string CStackDirectory::GetStackedTitlePath(const std::string &strPath, VECCREGEXP& RegExps) { CStackDirectory stack; CFileItemList files; std::string strStackTitlePath, strCommonDir = URIUtils::GetParentPath(strPath); const CURL pathToUrl(strPath); stack.GetDirectory(pathToUrl, files); if (files.Size() > 1) { std::string strStackTitle; std::string File1 = URIUtils::GetFileName(files[0]->GetPath()); std::string File2 = URIUtils::GetFileName(files[1]->GetPath()); // Check if source path uses URL encoding if (URIUtils::HasEncodedFilename(CURL(strCommonDir))) { File1 = CURL::Decode(File1); File2 = CURL::Decode(File2); } std::vector<CRegExp>::iterator itRegExp = RegExps.begin(); int offset = 0; while (itRegExp != RegExps.end()) { if (itRegExp->RegFind(File1, offset) != -1) { std::string Title1 = itRegExp->GetMatch(1), Volume1 = itRegExp->GetMatch(2), Ignore1 = itRegExp->GetMatch(3), Extension1 = itRegExp->GetMatch(4); if (offset) Title1 = File1.substr(0, itRegExp->GetSubStart(2)); if (itRegExp->RegFind(File2, offset) != -1) { std::string Title2 = itRegExp->GetMatch(1), Volume2 = itRegExp->GetMatch(2), Ignore2 = itRegExp->GetMatch(3), Extension2 = itRegExp->GetMatch(4); if (offset) Title2 = File2.substr(0, itRegExp->GetSubStart(2)); if (StringUtils::EqualsNoCase(Title1, Title2)) { if (!StringUtils::EqualsNoCase(Volume1, Volume2)) { if (StringUtils::EqualsNoCase(Ignore1, Ignore2) && StringUtils::EqualsNoCase(Extension1, Extension2)) { // got it strStackTitle = Title1 + Ignore1 + Extension1; // Check if source path uses URL encoding if (URIUtils::HasEncodedFilename(CURL(strCommonDir))) strStackTitle = CURL::Encode(strStackTitle); itRegExp = RegExps.end(); break; } else // Invalid stack break; } else // Early match, retry with offset { offset = itRegExp->GetSubStart(3); continue; } } } } offset = 0; itRegExp++; } if (!strCommonDir.empty() && !strStackTitle.empty()) strStackTitlePath = strCommonDir + strStackTitle; } return strStackTitlePath; }
/* Test case to test for graceful handling of corrupted input. * NOTE: The test case is considered a "success" as long as the corrupted * file was successfully generated and the test case runs without a segfault. */ TEST_F(TestZipFile, CorruptedFile) { XFILE::CFile *file; char buf[16]; memset(&buf, 0, sizeof(buf)); std::string reffilepath, strpathinzip, str; CFileItemList itemlist; unsigned int size, i; int64_t count = 0; reffilepath = XBMC_REF_FILE_PATH("xbmc/filesystem/test/reffile.txt.zip"); ASSERT_TRUE((file = XBMC_CREATECORRUPTEDFILE(reffilepath, ".zip")) != NULL); std::cout << "Reference file generated at '" << XBMC_TEMPFILEPATH(file) << "'" << std::endl; CURL zipUrl = URIUtils::CreateArchivePath("zip", CURL(reffilepath), ""); if (!XFILE::CDirectory::GetDirectory(zipUrl, itemlist, "", XFILE::DIR_FLAG_NO_FILE_DIRS)) { XBMC_DELETETEMPFILE(file); SUCCEED(); return; } if (itemlist.IsEmpty()) { XBMC_DELETETEMPFILE(file); SUCCEED(); return; } strpathinzip = itemlist[0]->GetPath(); if (!file->Open(strpathinzip)) { XBMC_DELETETEMPFILE(file); SUCCEED(); return; } std::cout << "file->GetLength(): " << testing::PrintToString(file->GetLength()) << std::endl; std::cout << "file->Seek(file->GetLength() / 2, SEEK_CUR) return value: " << testing::PrintToString(file->Seek(file->GetLength() / 2, SEEK_CUR)) << std::endl; std::cout << "file->Seek(0, SEEK_END) return value: " << testing::PrintToString(file->Seek(0, SEEK_END)) << std::endl; std::cout << "file->Seek(0, SEEK_SET) return value: " << testing::PrintToString(file->Seek(0, SEEK_SET)) << std::endl; std::cout << "File contents:" << std::endl; while ((size = file->Read(buf, sizeof(buf))) > 0) { str = StringUtils::Format(" %08lX", count); std::cout << str << " "; count += size; for (i = 0; i < size; i++) { str = StringUtils::Format("%02X ", buf[i]); std::cout << str; } while (i++ < sizeof(buf)) std::cout << " "; std::cout << " ["; for (i = 0; i < size; i++) { if (buf[i] >= ' ' && buf[i] <= '~') std::cout << buf[i]; else std::cout << "."; } std::cout << "]" << std::endl; } file->Close(); XBMC_DELETETEMPFILE(file); }
void CVFSEntryIDirectoryWrapper::DoRequireAuthentication(void* ctx, const char* url) { static_cast<CVFSEntryIDirectoryWrapper*>(ctx)->RequireAuthentication2(CURL(url)); }
bool CKeyboardLayoutManager::Load(const std::string& path /* = "" */) { std::string layoutDirectory = path; if (layoutDirectory.empty()) layoutDirectory = KEYBOARD_LAYOUTS_PATH; if (!XFILE::CDirectory::Exists(layoutDirectory)) { CLog::Log(LOGWARNING, "CKeyboardLayoutManager: unable to load keyboard layouts from non-existing directory \"%s\"", layoutDirectory.c_str()); return false; } CFileItemList layouts; if (!XFILE::CDirectory::GetDirectory(CURL(layoutDirectory), layouts, ".xml") || layouts.IsEmpty()) { CLog::Log(LOGWARNING, "CKeyboardLayoutManager: no keyboard layouts found in %s", layoutDirectory.c_str()); return false; } CLog::Log(LOGINFO, "CKeyboardLayoutManager: loading keyboard layouts from %s...", layoutDirectory.c_str()); size_t oldLayoutCount = m_layouts.size(); for (int i = 0; i < layouts.Size(); i++) { std::string layoutPath = layouts[i]->GetPath(); if (layoutPath.empty()) continue; CXBMCTinyXML xmlDoc; if (!xmlDoc.LoadFile(layoutPath)) { CLog::Log(LOGWARNING, "CKeyboardLayoutManager: unable to open %s", layoutPath.c_str()); continue; } const TiXmlElement* rootElement = xmlDoc.RootElement(); if (rootElement == NULL) { CLog::Log(LOGWARNING, "CKeyboardLayoutManager: missing or invalid XML root element in %s", layoutPath.c_str()); continue; } if (rootElement->ValueStr() != "keyboardlayouts") { CLog::Log(LOGWARNING, "CKeyboardLayoutManager: unexpected XML root element \"%s\" in %s", rootElement->Value(), layoutPath.c_str()); continue; } const TiXmlElement* layoutElement = rootElement->FirstChildElement("layout"); while (layoutElement != NULL) { CKeyboardLayout layout; if (!layout.Load(layoutElement)) CLog::Log(LOGWARNING, "CKeyboardLayoutManager: failed to load %s", layoutPath.c_str()); else if (m_layouts.find(layout.GetIdentifier()) != m_layouts.end()) CLog::Log(LOGWARNING, "CKeyboardLayoutManager: duplicate layout with identifier \"%s\" in %s", layout.GetIdentifier().c_str(), layoutPath.c_str()); else { CLog::Log(LOGDEBUG, "CKeyboardLayoutManager: keyboard layout \"%s\" successfully loaded", layout.GetIdentifier().c_str()); m_layouts.insert(std::make_pair(layout.GetIdentifier(), layout)); } layoutElement = layoutElement->NextSiblingElement(); } } return m_layouts.size() > oldLayoutCount; }
CHTTPVfsHandler::CHTTPVfsHandler(const HTTPRequest &request) : CHTTPFileHandler(request) { std::string file; int responseStatus = MHD_HTTP_BAD_REQUEST; if (m_request.pathUrl.size() > 5) { file = m_request.pathUrl.substr(5); if (XFILE::CFile::Exists(file)) { bool accessible = false; if (file.substr(0, 8) == "image://") accessible = true; else { std::string sourceTypes[] = { "video", "music", "pictures" }; unsigned int size = sizeof(sourceTypes) / sizeof(std::string); std::string realPath = URIUtils::GetRealPath(file); // for rar:// and zip:// paths we need to extract the path to the archive instead of using the VFS path while (URIUtils::IsInArchive(realPath)) realPath = CURL(realPath).GetHostName(); VECSOURCES *sources = NULL; for (unsigned int index = 0; index < size && !accessible; index++) { sources = CMediaSourceSettings::GetInstance().GetSources(sourceTypes[index]); if (sources == NULL) continue; for (VECSOURCES::const_iterator source = sources->begin(); source != sources->end() && !accessible; ++source) { // don't allow access to locked / disabled sharing sources if (source->m_iHasLock == 2 || !source->m_allowSharing) continue; for (std::vector<std::string>::const_iterator path = source->vecPaths.begin(); path != source->vecPaths.end(); ++path) { std::string realSourcePath = URIUtils::GetRealPath(*path); if (URIUtils::PathHasParent(realPath, realSourcePath, true)) { accessible = true; break; } } } } } if (accessible) responseStatus = MHD_HTTP_OK; // the file exists but not in one of the defined sources so we deny access to it else responseStatus = MHD_HTTP_UNAUTHORIZED; } else responseStatus = MHD_HTTP_NOT_FOUND; } // set the file and the HTTP response status SetFile(file, responseStatus); }
if (chunk == NULL) exit(EXIT_FAILURE); chunk->data = NULL; chunk->size = 0; return chunk; } void arc_curl_cleanup_chunk(chunk_t *chunk) { free(chunk->data); free(chunk); } char* arc_curl_get(CURL *curl, const char* url, chunk_t *chunk, int verbose) { CURL("GET", curl, url, chunk, verbose) } char* arc_curl_post(CURL *curl, const char* url, const char* data, chunk_t *chunk, int verbose) { SET_DATA(curl, data); CURL("POST", curl, url, chunk, verbose) } char* arc_curl_put(CURL *curl, const char* url, const char* data, chunk_t *chunk, int verbose) { SET_DATA(curl, data); CURL("PUT", curl, url, chunk, verbose) } char* arc_curl_del(CURL *curl, const char* url, chunk_t *chunk, int verbose)