13e5483f6Sopenharmony_ci/* 23e5483f6Sopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd. 33e5483f6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43e5483f6Sopenharmony_ci * you may not use this file except in compliance with the License. 53e5483f6Sopenharmony_ci * You may obtain a copy of the License at 63e5483f6Sopenharmony_ci * 73e5483f6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83e5483f6Sopenharmony_ci * 93e5483f6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103e5483f6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113e5483f6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123e5483f6Sopenharmony_ci * See the License for the specific language governing permissions and 133e5483f6Sopenharmony_ci * limitations under the License. 143e5483f6Sopenharmony_ci */ 153e5483f6Sopenharmony_ci#define MLOG_TAG "FileUtils" 163e5483f6Sopenharmony_ci 173e5483f6Sopenharmony_ci#include "ringtone_file_utils.h" 183e5483f6Sopenharmony_ci 193e5483f6Sopenharmony_ci#include <dirent.h> 203e5483f6Sopenharmony_ci#include <fcntl.h> 213e5483f6Sopenharmony_ci#include <ftw.h> 223e5483f6Sopenharmony_ci#include <fstream> 233e5483f6Sopenharmony_ci#include <sstream> 243e5483f6Sopenharmony_ci#include <sys/sendfile.h> 253e5483f6Sopenharmony_ci#include <unistd.h> 263e5483f6Sopenharmony_ci#include <iostream> 273e5483f6Sopenharmony_ci 283e5483f6Sopenharmony_ci#include "directory_ex.h" 293e5483f6Sopenharmony_ci#include "ringtone_db_const.h" 303e5483f6Sopenharmony_ci#include "ringtone_errno.h" 313e5483f6Sopenharmony_ci#include "ringtone_log.h" 323e5483f6Sopenharmony_ci#include "ringtone_mimetype_utils.h" 333e5483f6Sopenharmony_ci#include "ringtone_type.h" 343e5483f6Sopenharmony_ci#include "vibrate_type.h" 353e5483f6Sopenharmony_ci#include "securec.h" 363e5483f6Sopenharmony_ci 373e5483f6Sopenharmony_cinamespace OHOS { 383e5483f6Sopenharmony_cinamespace Media { 393e5483f6Sopenharmony_ciusing namespace std; 403e5483f6Sopenharmony_cistatic const int32_t OPEN_FDS = 128; 413e5483f6Sopenharmony_cistatic const mode_t MODE_RWX_USR_GRP = 02771; 423e5483f6Sopenharmony_cistatic const mode_t MODE_RW_USR = 0644; 433e5483f6Sopenharmony_ciconst vector<string> EXIF_SUPPORTED_EXTENSION = { 443e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_3GA, 453e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_AC3, 463e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_A52, 473e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_AMR, 483e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_IMY, 493e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_RTTTL, 503e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_XMF, 513e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_RTX, 523e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_MXMF, 533e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_M4A, 543e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_M4B, 553e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_M4P, 563e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_F4A, 573e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_F4B, 583e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_F4P, 593e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_M3U, 603e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_SMF, 613e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_MKA, 623e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_RA, 633e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_MP3, 643e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_AAC, 653e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_ADTS, 663e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_ADT, 673e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_SND, 683e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_FLAC, 693e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_MP2, 703e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_MP1, 713e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_MPA, 723e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_M4R, 733e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_WAV, 743e5483f6Sopenharmony_ci RINGTONE_CONTAINER_TYPE_OGG 753e5483f6Sopenharmony_ci}; 763e5483f6Sopenharmony_ci 773e5483f6Sopenharmony_cistatic bool IsTargetExtension(const string &path) 783e5483f6Sopenharmony_ci{ 793e5483f6Sopenharmony_ci const string ext = RingtoneFileUtils::GetExtensionFromPath(path); 803e5483f6Sopenharmony_ci std::string mimeType = RingtoneMimeTypeUtils::GetMimeTypeFromExtension(ext); 813e5483f6Sopenharmony_ci int32_t mime = RingtoneMimeTypeUtils::GetMediaTypeFromMimeType(mimeType); 823e5483f6Sopenharmony_ci if (mime == RINGTONE_MEDIA_TYPE_AUDIO) { 833e5483f6Sopenharmony_ci return true; 843e5483f6Sopenharmony_ci } 853e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("MimeType error:%{public}s,%{public}s", ext.c_str(), mimeType.c_str()); 863e5483f6Sopenharmony_ci bool ret = find(EXIF_SUPPORTED_EXTENSION.begin(), EXIF_SUPPORTED_EXTENSION.end(), ext) != 873e5483f6Sopenharmony_ci EXIF_SUPPORTED_EXTENSION.end(); 883e5483f6Sopenharmony_ci if (!ret) { 893e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("invalid target extension:%{public}s", ext.c_str()); 903e5483f6Sopenharmony_ci } 913e5483f6Sopenharmony_ci return ret; 923e5483f6Sopenharmony_ci} 933e5483f6Sopenharmony_ci 943e5483f6Sopenharmony_cistatic bool IsVibrateFile(const string &path) 953e5483f6Sopenharmony_ci{ 963e5483f6Sopenharmony_ci const string ext = RingtoneFileUtils::GetExtensionFromPath(path); 973e5483f6Sopenharmony_ci bool ret = (ext == VIBRATE_CONTAINER_TYPE_JSON); 983e5483f6Sopenharmony_ci if (!ret) { 993e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("invalid target extension:%{public}s", ext.c_str()); 1003e5483f6Sopenharmony_ci } 1013e5483f6Sopenharmony_ci return ret; 1023e5483f6Sopenharmony_ci} 1033e5483f6Sopenharmony_ci 1043e5483f6Sopenharmony_cistring RingtoneFileUtils::SplitByChar(const string &str, const char split) 1053e5483f6Sopenharmony_ci{ 1063e5483f6Sopenharmony_ci size_t splitIndex = str.find_last_of(split); 1073e5483f6Sopenharmony_ci return (splitIndex == string::npos) ? ("") : (str.substr(splitIndex + 1)); 1083e5483f6Sopenharmony_ci} 1093e5483f6Sopenharmony_ci 1103e5483f6Sopenharmony_cistring RingtoneFileUtils::GetExtensionFromPath(const string &path) 1113e5483f6Sopenharmony_ci{ 1123e5483f6Sopenharmony_ci string extention = SplitByChar(path, '.'); 1133e5483f6Sopenharmony_ci if (!extention.empty()) { 1143e5483f6Sopenharmony_ci transform(extention.begin(), extention.end(), extention.begin(), ::tolower); 1153e5483f6Sopenharmony_ci } 1163e5483f6Sopenharmony_ci return extention; 1173e5483f6Sopenharmony_ci} 1183e5483f6Sopenharmony_ci 1193e5483f6Sopenharmony_cistring RingtoneFileUtils::GetFileNameFromPath(const string &path) 1203e5483f6Sopenharmony_ci{ 1213e5483f6Sopenharmony_ci string fileName = {}; 1223e5483f6Sopenharmony_ci size_t found = path.rfind("/"); 1233e5483f6Sopenharmony_ci if (found != string::npos && (found + 1) < path.size()) { 1243e5483f6Sopenharmony_ci fileName = path.substr(found + 1); 1253e5483f6Sopenharmony_ci } else { 1263e5483f6Sopenharmony_ci fileName = ""; 1273e5483f6Sopenharmony_ci } 1283e5483f6Sopenharmony_ci 1293e5483f6Sopenharmony_ci return fileName; 1303e5483f6Sopenharmony_ci} 1313e5483f6Sopenharmony_ci 1323e5483f6Sopenharmony_cistatic string ParseFromUri(const string& path, const string& key) 1333e5483f6Sopenharmony_ci{ 1343e5483f6Sopenharmony_ci RINGTONE_INFO_LOG("parsing uri : %{public}s for key : %{public}s", path.c_str(), key.c_str()); 1353e5483f6Sopenharmony_ci auto keyLen = key.size(); 1363e5483f6Sopenharmony_ci auto found = path.find(key); 1373e5483f6Sopenharmony_ci if (found == string::npos) { 1383e5483f6Sopenharmony_ci RINGTONE_INFO_LOG("there is no such field in uri: %{public}s", path.c_str()); 1393e5483f6Sopenharmony_ci return ""; 1403e5483f6Sopenharmony_ci } 1413e5483f6Sopenharmony_ci string sub = path.substr(found + keyLen + 1); 1423e5483f6Sopenharmony_ci found = sub.find("&"); 1433e5483f6Sopenharmony_ci if (found != string::npos) { 1443e5483f6Sopenharmony_ci sub = sub.substr(0, found); 1453e5483f6Sopenharmony_ci } 1463e5483f6Sopenharmony_ci sub = RingtoneFileUtils::UrlDecode(sub); 1473e5483f6Sopenharmony_ci RINGTONE_INFO_LOG("parsing uri : %{public}s -> key=%{public}s, value=%{public}s", 1483e5483f6Sopenharmony_ci path.c_str(), key.c_str(), sub.c_str()); 1493e5483f6Sopenharmony_ci return sub; 1503e5483f6Sopenharmony_ci} 1513e5483f6Sopenharmony_ci 1523e5483f6Sopenharmony_cistring RingtoneFileUtils::GetFileNameFromPathOrUri(const string &path, bool &isTitle) 1533e5483f6Sopenharmony_ci{ 1543e5483f6Sopenharmony_ci string fileName = {}; 1553e5483f6Sopenharmony_ci size_t found = path.find("content://"); 1563e5483f6Sopenharmony_ci if (found == 0) { 1573e5483f6Sopenharmony_ci fileName = ParseFromUri(path, "title"); // Pay attention! It's actually "title". 1583e5483f6Sopenharmony_ci isTitle = true; 1593e5483f6Sopenharmony_ci } else { 1603e5483f6Sopenharmony_ci fileName = GetFileNameFromPath(path); 1613e5483f6Sopenharmony_ci isTitle = false; 1623e5483f6Sopenharmony_ci } 1633e5483f6Sopenharmony_ci RINGTONE_INFO_LOG("%{public}s -> %{public}s", path.c_str(), fileName.c_str()); 1643e5483f6Sopenharmony_ci return fileName; 1653e5483f6Sopenharmony_ci} 1663e5483f6Sopenharmony_ci 1673e5483f6Sopenharmony_cistring RingtoneFileUtils::GetBaseNameFromPath(const string &path) 1683e5483f6Sopenharmony_ci{ 1693e5483f6Sopenharmony_ci size_t found = path.rfind("/"); 1703e5483f6Sopenharmony_ci size_t foundDot = path.rfind("."); 1713e5483f6Sopenharmony_ci 1723e5483f6Sopenharmony_ci string baseName = {}; 1733e5483f6Sopenharmony_ci found = (found == string::npos ? 0 : found); 1743e5483f6Sopenharmony_ci if ((foundDot > found) && (foundDot != string::npos)) { 1753e5483f6Sopenharmony_ci baseName = path.substr(found + 1, foundDot - found - 1); 1763e5483f6Sopenharmony_ci } else { 1773e5483f6Sopenharmony_ci baseName = ""; 1783e5483f6Sopenharmony_ci } 1793e5483f6Sopenharmony_ci 1803e5483f6Sopenharmony_ci return baseName; 1813e5483f6Sopenharmony_ci} 1823e5483f6Sopenharmony_ci 1833e5483f6Sopenharmony_cibool RingtoneFileUtils::IsSameFile(const string &srcPath, const string &dstPath) 1843e5483f6Sopenharmony_ci{ 1853e5483f6Sopenharmony_ci struct stat srcStatInfo {}; 1863e5483f6Sopenharmony_ci struct stat dstStatInfo {}; 1873e5483f6Sopenharmony_ci 1883e5483f6Sopenharmony_ci if (access(srcPath.c_str(), F_OK) || access(dstPath.c_str(), F_OK)) { 1893e5483f6Sopenharmony_ci return false; 1903e5483f6Sopenharmony_ci } 1913e5483f6Sopenharmony_ci if (stat(srcPath.c_str(), &srcStatInfo) != 0) { 1923e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Failed to get file %{private}s StatInfo, err=%{public}d", srcPath.c_str(), errno); 1933e5483f6Sopenharmony_ci return false; 1943e5483f6Sopenharmony_ci } 1953e5483f6Sopenharmony_ci if (stat(dstPath.c_str(), &dstStatInfo) != 0) { 1963e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Failed to get file %{private}s StatInfo, err=%{public}d", dstPath.c_str(), errno); 1973e5483f6Sopenharmony_ci return false; 1983e5483f6Sopenharmony_ci } 1993e5483f6Sopenharmony_ci if (srcStatInfo.st_size != dstStatInfo.st_size) { /* file size */ 2003e5483f6Sopenharmony_ci RINGTONE_INFO_LOG("Size differs, srcStatInfo.st_size != dstStatInfo.st_size"); 2013e5483f6Sopenharmony_ci return false; 2023e5483f6Sopenharmony_ci } 2033e5483f6Sopenharmony_ci 2043e5483f6Sopenharmony_ci return true; 2053e5483f6Sopenharmony_ci} 2063e5483f6Sopenharmony_ci 2073e5483f6Sopenharmony_cistatic int32_t UnlinkCb(const char *fpath, const struct stat *sb, int32_t typeflag, struct FTW *ftwbuf) 2083e5483f6Sopenharmony_ci{ 2093e5483f6Sopenharmony_ci CHECK_AND_RETURN_RET_LOG(fpath != nullptr, E_FAIL, "fpath == nullptr"); 2103e5483f6Sopenharmony_ci int32_t errRet = remove(fpath); 2113e5483f6Sopenharmony_ci if (errRet) { 2123e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Failed to remove errno: %{public}d, path: %{private}s", errno, fpath); 2133e5483f6Sopenharmony_ci } 2143e5483f6Sopenharmony_ci 2153e5483f6Sopenharmony_ci return errRet; 2163e5483f6Sopenharmony_ci} 2173e5483f6Sopenharmony_ci 2183e5483f6Sopenharmony_ciint32_t RingtoneFileUtils::RemoveDirectory(const string &path) 2193e5483f6Sopenharmony_ci{ 2203e5483f6Sopenharmony_ci return nftw(path.c_str(), UnlinkCb, OPEN_FDS, FTW_DEPTH | FTW_PHYS); 2213e5483f6Sopenharmony_ci} 2223e5483f6Sopenharmony_ci 2233e5483f6Sopenharmony_cibool RingtoneFileUtils::Mkdir(const string &subStr, shared_ptr<int> errCodePtr) 2243e5483f6Sopenharmony_ci{ 2253e5483f6Sopenharmony_ci mode_t mask = umask(0); 2263e5483f6Sopenharmony_ci if (mkdir(subStr.c_str(), MODE_RWX_USR_GRP) == -1) { 2273e5483f6Sopenharmony_ci if (errCodePtr != nullptr) { 2283e5483f6Sopenharmony_ci *errCodePtr = errno; 2293e5483f6Sopenharmony_ci } 2303e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Failed to create directory %{public}d", errno); 2313e5483f6Sopenharmony_ci umask(mask); 2323e5483f6Sopenharmony_ci return (errno == EEXIST) ? true : false; 2333e5483f6Sopenharmony_ci } 2343e5483f6Sopenharmony_ci umask(mask); 2353e5483f6Sopenharmony_ci return true; 2363e5483f6Sopenharmony_ci} 2373e5483f6Sopenharmony_ci 2383e5483f6Sopenharmony_cibool RingtoneFileUtils::IsDirectory(const string &dirName, shared_ptr<int> errCodePtr) 2393e5483f6Sopenharmony_ci{ 2403e5483f6Sopenharmony_ci struct stat statInfo {}; 2413e5483f6Sopenharmony_ci 2423e5483f6Sopenharmony_ci if (stat(dirName.c_str(), &statInfo) == 0) { 2433e5483f6Sopenharmony_ci if (statInfo.st_mode & S_IFDIR) { 2443e5483f6Sopenharmony_ci return true; 2453e5483f6Sopenharmony_ci } 2463e5483f6Sopenharmony_ci } else if (errCodePtr != nullptr) { 2473e5483f6Sopenharmony_ci *errCodePtr = errno; 2483e5483f6Sopenharmony_ci return false; 2493e5483f6Sopenharmony_ci } 2503e5483f6Sopenharmony_ci 2513e5483f6Sopenharmony_ci return false; 2523e5483f6Sopenharmony_ci} 2533e5483f6Sopenharmony_ci 2543e5483f6Sopenharmony_cibool RingtoneFileUtils::CreateDirectory(const string &dirPath, shared_ptr<int> errCodePtr) 2553e5483f6Sopenharmony_ci{ 2563e5483f6Sopenharmony_ci string subStr; 2573e5483f6Sopenharmony_ci string segment; 2583e5483f6Sopenharmony_ci 2593e5483f6Sopenharmony_ci stringstream folderStream(dirPath); 2603e5483f6Sopenharmony_ci while (getline(folderStream, segment, '/')) { 2613e5483f6Sopenharmony_ci if (segment.empty()) { 2623e5483f6Sopenharmony_ci continue; 2633e5483f6Sopenharmony_ci } 2643e5483f6Sopenharmony_ci 2653e5483f6Sopenharmony_ci subStr.append(RINGTONE_SLASH_CHAR + segment); 2663e5483f6Sopenharmony_ci if (!IsDirectory(subStr, errCodePtr)) { 2673e5483f6Sopenharmony_ci if (!Mkdir(subStr, errCodePtr)) { 2683e5483f6Sopenharmony_ci return false; 2693e5483f6Sopenharmony_ci } 2703e5483f6Sopenharmony_ci } 2713e5483f6Sopenharmony_ci } 2723e5483f6Sopenharmony_ci return true; 2733e5483f6Sopenharmony_ci} 2743e5483f6Sopenharmony_ci 2753e5483f6Sopenharmony_ciint32_t RingtoneFileUtils::OpenFile(const string &filePath, const string &mode) 2763e5483f6Sopenharmony_ci{ 2773e5483f6Sopenharmony_ci int32_t errCode = E_ERR; 2783e5483f6Sopenharmony_ci 2793e5483f6Sopenharmony_ci if (filePath.empty() || mode.empty()) { 2803e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Invalid open argument! mode: %{private}s, path: %{private}s", mode.c_str(), filePath.c_str()); 2813e5483f6Sopenharmony_ci return errCode; 2823e5483f6Sopenharmony_ci } 2833e5483f6Sopenharmony_ci 2843e5483f6Sopenharmony_ci if (!IsTargetExtension(filePath)) { 2853e5483f6Sopenharmony_ci return E_INVALID_PATH; 2863e5483f6Sopenharmony_ci } 2873e5483f6Sopenharmony_ci 2883e5483f6Sopenharmony_ci static const unordered_map<string, int32_t> RINGTONE_OPEN_MODE_MAP = { 2893e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_READONLY, O_RDONLY }, 2903e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_WRITEONLY, O_WRONLY }, 2913e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_READWRITE, O_RDWR }, 2923e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_WRITETRUNCATE, O_WRONLY | O_TRUNC }, 2933e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_WRITEAPPEND, O_WRONLY | O_APPEND }, 2943e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_READWRITETRUNCATE, O_RDWR | O_TRUNC }, 2953e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_READWRITEAPPEND, O_RDWR | O_APPEND }, 2963e5483f6Sopenharmony_ci }; 2973e5483f6Sopenharmony_ci if (RINGTONE_OPEN_MODE_MAP.find(mode) == RINGTONE_OPEN_MODE_MAP.end()) { 2983e5483f6Sopenharmony_ci return E_ERR; 2993e5483f6Sopenharmony_ci } 3003e5483f6Sopenharmony_ci 3013e5483f6Sopenharmony_ci if (filePath.size() >= PATH_MAX) { 3023e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("File path too long %{public}d", (int)filePath.size()); 3033e5483f6Sopenharmony_ci return errCode; 3043e5483f6Sopenharmony_ci } 3053e5483f6Sopenharmony_ci string absFilePath; 3063e5483f6Sopenharmony_ci if (!PathToRealPath(filePath, absFilePath)) { 3073e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("file is not real path, file path: %{private}s", filePath.c_str()); 3083e5483f6Sopenharmony_ci return errCode; 3093e5483f6Sopenharmony_ci } 3103e5483f6Sopenharmony_ci if (absFilePath.empty()) { 3113e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Failed to obtain the canonical path for source path %{public}d %{private}s", 3123e5483f6Sopenharmony_ci errno, filePath.c_str()); 3133e5483f6Sopenharmony_ci return errCode; 3143e5483f6Sopenharmony_ci } 3153e5483f6Sopenharmony_ci RINGTONE_INFO_LOG("File absFilePath is %{private}s", absFilePath.c_str()); 3163e5483f6Sopenharmony_ci return open(absFilePath.c_str(), RINGTONE_OPEN_MODE_MAP.at(mode)); 3173e5483f6Sopenharmony_ci} 3183e5483f6Sopenharmony_ci 3193e5483f6Sopenharmony_ciint32_t RingtoneFileUtils::OpenVibrateFile(const std::string &filePath, const std::string &mode) 3203e5483f6Sopenharmony_ci{ 3213e5483f6Sopenharmony_ci int32_t errCode = E_ERR; 3223e5483f6Sopenharmony_ci 3233e5483f6Sopenharmony_ci if (filePath.empty() || mode.empty()) { 3243e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Invalid open argument! mode: %{private}s, path: %{private}s", mode.c_str(), filePath.c_str()); 3253e5483f6Sopenharmony_ci return errCode; 3263e5483f6Sopenharmony_ci } 3273e5483f6Sopenharmony_ci 3283e5483f6Sopenharmony_ci if (!IsVibrateFile(filePath)) { 3293e5483f6Sopenharmony_ci return E_INVALID_PATH; 3303e5483f6Sopenharmony_ci } 3313e5483f6Sopenharmony_ci 3323e5483f6Sopenharmony_ci static const unordered_map<string, int32_t> RINGTONE_OPEN_MODE_MAP = { 3333e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_READONLY, O_RDONLY }, 3343e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_WRITEONLY, O_WRONLY }, 3353e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_READWRITE, O_RDWR }, 3363e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_WRITETRUNCATE, O_WRONLY | O_TRUNC }, 3373e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_WRITEAPPEND, O_WRONLY | O_APPEND }, 3383e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_READWRITETRUNCATE, O_RDWR | O_TRUNC }, 3393e5483f6Sopenharmony_ci { RINGTONE_FILEMODE_READWRITEAPPEND, O_RDWR | O_APPEND }, 3403e5483f6Sopenharmony_ci }; 3413e5483f6Sopenharmony_ci if (RINGTONE_OPEN_MODE_MAP.find(mode) == RINGTONE_OPEN_MODE_MAP.end()) { 3423e5483f6Sopenharmony_ci return E_ERR; 3433e5483f6Sopenharmony_ci } 3443e5483f6Sopenharmony_ci 3453e5483f6Sopenharmony_ci if (filePath.size() >= PATH_MAX) { 3463e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("File path too long %{public}d", (int)filePath.size()); 3473e5483f6Sopenharmony_ci return errCode; 3483e5483f6Sopenharmony_ci } 3493e5483f6Sopenharmony_ci string absFilePath; 3503e5483f6Sopenharmony_ci if (!PathToRealPath(filePath, absFilePath)) { 3513e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("file is not real path, file path: %{private}s", filePath.c_str()); 3523e5483f6Sopenharmony_ci return errCode; 3533e5483f6Sopenharmony_ci } 3543e5483f6Sopenharmony_ci if (absFilePath.empty()) { 3553e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Failed to obtain the canonical path for source path %{public}d %{private}s", 3563e5483f6Sopenharmony_ci errno, filePath.c_str()); 3573e5483f6Sopenharmony_ci return errCode; 3583e5483f6Sopenharmony_ci } 3593e5483f6Sopenharmony_ci RINGTONE_INFO_LOG("File absFilePath is %{private}s", absFilePath.c_str()); 3603e5483f6Sopenharmony_ci return open(absFilePath.c_str(), RINGTONE_OPEN_MODE_MAP.at(mode)); 3613e5483f6Sopenharmony_ci} 3623e5483f6Sopenharmony_ci 3633e5483f6Sopenharmony_cibool RingtoneFileUtils::IsFileExists(const string &fileName) 3643e5483f6Sopenharmony_ci{ 3653e5483f6Sopenharmony_ci struct stat statInfo {}; 3663e5483f6Sopenharmony_ci 3673e5483f6Sopenharmony_ci return ((stat(fileName.c_str(), &statInfo)) == 0); 3683e5483f6Sopenharmony_ci} 3693e5483f6Sopenharmony_ci 3703e5483f6Sopenharmony_ciint32_t RingtoneFileUtils::CreateFile(const string &filePath) 3713e5483f6Sopenharmony_ci{ 3723e5483f6Sopenharmony_ci int32_t errCode = E_ERR; 3733e5483f6Sopenharmony_ci 3743e5483f6Sopenharmony_ci if (filePath.empty()) { 3753e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Filepath is empty"); 3763e5483f6Sopenharmony_ci return E_VIOLATION_PARAMETERS; 3773e5483f6Sopenharmony_ci } 3783e5483f6Sopenharmony_ci 3793e5483f6Sopenharmony_ci if (!IsTargetExtension(filePath)) { 3803e5483f6Sopenharmony_ci return E_INVALID_PATH; 3813e5483f6Sopenharmony_ci } 3823e5483f6Sopenharmony_ci 3833e5483f6Sopenharmony_ci if (IsFileExists(filePath)) { 3843e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("the file exists path: %{private}s", filePath.c_str()); 3853e5483f6Sopenharmony_ci return E_FILE_EXIST; 3863e5483f6Sopenharmony_ci } 3873e5483f6Sopenharmony_ci 3883e5483f6Sopenharmony_ci ofstream file(filePath); 3893e5483f6Sopenharmony_ci if (!file) { 3903e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Output file path could not be created errno %{public}d", errno); 3913e5483f6Sopenharmony_ci return errCode; 3923e5483f6Sopenharmony_ci } 3933e5483f6Sopenharmony_ci 3943e5483f6Sopenharmony_ci file.close(); 3953e5483f6Sopenharmony_ci 3963e5483f6Sopenharmony_ci return E_SUCCESS; 3973e5483f6Sopenharmony_ci} 3983e5483f6Sopenharmony_ci 3993e5483f6Sopenharmony_cibool RingtoneFileUtils::DeleteFile(const string &fileName) 4003e5483f6Sopenharmony_ci{ 4013e5483f6Sopenharmony_ci return (remove(fileName.c_str()) == 0); 4023e5483f6Sopenharmony_ci} 4033e5483f6Sopenharmony_ci 4043e5483f6Sopenharmony_cibool RingtoneFileUtils::MoveFile(const string &oldPath, const string &newPath) 4053e5483f6Sopenharmony_ci{ 4063e5483f6Sopenharmony_ci bool errRet = false; 4073e5483f6Sopenharmony_ci 4083e5483f6Sopenharmony_ci if (IsFileExists(oldPath) && !IsFileExists(newPath)) { 4093e5483f6Sopenharmony_ci errRet = (rename(oldPath.c_str(), newPath.c_str()) == 0); 4103e5483f6Sopenharmony_ci } 4113e5483f6Sopenharmony_ci 4123e5483f6Sopenharmony_ci return errRet; 4133e5483f6Sopenharmony_ci} 4143e5483f6Sopenharmony_ci 4153e5483f6Sopenharmony_cibool RingtoneFileUtils::CopyFileUtil(const string &filePath, const string &newPath) 4163e5483f6Sopenharmony_ci{ 4173e5483f6Sopenharmony_ci struct stat fst{}; 4183e5483f6Sopenharmony_ci bool ret = false; 4193e5483f6Sopenharmony_ci if (filePath.size() >= PATH_MAX) { 4203e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("File path too long %{public}d", static_cast<int>(filePath.size())); 4213e5483f6Sopenharmony_ci return ret; 4223e5483f6Sopenharmony_ci } 4233e5483f6Sopenharmony_ci RINGTONE_INFO_LOG("File path is %{private}s", filePath.c_str()); 4243e5483f6Sopenharmony_ci string absFilePath; 4253e5483f6Sopenharmony_ci if (!PathToRealPath(filePath, absFilePath)) { 4263e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("file is not real path, file path: %{private}s", filePath.c_str()); 4273e5483f6Sopenharmony_ci return ret; 4283e5483f6Sopenharmony_ci } 4293e5483f6Sopenharmony_ci if (absFilePath.empty()) { 4303e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Failed to obtain the canonical path for source path%{private}s %{public}d", 4313e5483f6Sopenharmony_ci filePath.c_str(), errno); 4323e5483f6Sopenharmony_ci return ret; 4333e5483f6Sopenharmony_ci } 4343e5483f6Sopenharmony_ci 4353e5483f6Sopenharmony_ci int32_t source = open(absFilePath.c_str(), O_RDONLY); 4363e5483f6Sopenharmony_ci if (source == -1) { 4373e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Open failed for source file"); 4383e5483f6Sopenharmony_ci return ret; 4393e5483f6Sopenharmony_ci } 4403e5483f6Sopenharmony_ci 4413e5483f6Sopenharmony_ci int32_t dest = open(newPath.c_str(), O_WRONLY | O_CREAT, MODE_RW_USR); 4423e5483f6Sopenharmony_ci if (dest == -1) { 4433e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Open failed for destination file %{public}d", errno); 4443e5483f6Sopenharmony_ci close(source); 4453e5483f6Sopenharmony_ci return ret; 4463e5483f6Sopenharmony_ci } 4473e5483f6Sopenharmony_ci 4483e5483f6Sopenharmony_ci if (fstat(source, &fst) == 0) { 4493e5483f6Sopenharmony_ci // Copy file content 4503e5483f6Sopenharmony_ci if (sendfile(dest, source, nullptr, fst.st_size) != E_ERR) { 4513e5483f6Sopenharmony_ci // Copy ownership and mode of source file 4523e5483f6Sopenharmony_ci if (fchown(dest, fst.st_uid, fst.st_gid) == 0 && 4533e5483f6Sopenharmony_ci fchmod(dest, fst.st_mode) == 0) { 4543e5483f6Sopenharmony_ci ret= true; 4553e5483f6Sopenharmony_ci } 4563e5483f6Sopenharmony_ci } 4573e5483f6Sopenharmony_ci } 4583e5483f6Sopenharmony_ci 4593e5483f6Sopenharmony_ci close(source); 4603e5483f6Sopenharmony_ci close(dest); 4613e5483f6Sopenharmony_ci 4623e5483f6Sopenharmony_ci return ret; 4633e5483f6Sopenharmony_ci} 4643e5483f6Sopenharmony_ci 4653e5483f6Sopenharmony_ciint64_t RingtoneFileUtils::Timespec2Millisecond(const struct timespec &time) 4663e5483f6Sopenharmony_ci{ 4673e5483f6Sopenharmony_ci return time.tv_sec * MSEC_TO_SEC + time.tv_nsec / MSEC_TO_NSEC; 4683e5483f6Sopenharmony_ci} 4693e5483f6Sopenharmony_ci 4703e5483f6Sopenharmony_cibool RingtoneFileUtils::StartsWith(const string &str, const string &prefix) 4713e5483f6Sopenharmony_ci{ 4723e5483f6Sopenharmony_ci return str.compare(0, prefix.size(), prefix) == 0; 4733e5483f6Sopenharmony_ci} 4743e5483f6Sopenharmony_ci 4753e5483f6Sopenharmony_ciint64_t RingtoneFileUtils::UTCTimeMilliSeconds() 4763e5483f6Sopenharmony_ci{ 4773e5483f6Sopenharmony_ci struct timespec t; 4783e5483f6Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &t); 4793e5483f6Sopenharmony_ci return t.tv_sec * MSEC_TO_SEC + t.tv_nsec / MSEC_TO_NSEC; 4803e5483f6Sopenharmony_ci} 4813e5483f6Sopenharmony_ci 4823e5483f6Sopenharmony_ciint64_t RingtoneFileUtils::UTCTimeSeconds() 4833e5483f6Sopenharmony_ci{ 4843e5483f6Sopenharmony_ci struct timespec t{}; 4853e5483f6Sopenharmony_ci t.tv_sec = 0; 4863e5483f6Sopenharmony_ci t.tv_nsec = 0; 4873e5483f6Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &t); 4883e5483f6Sopenharmony_ci return (int64_t)(t.tv_sec); 4893e5483f6Sopenharmony_ci} 4903e5483f6Sopenharmony_ci 4913e5483f6Sopenharmony_cistring RingtoneFileUtils::StrCreateTimeByMilliseconds(const string &format, int64_t time) 4923e5483f6Sopenharmony_ci{ 4933e5483f6Sopenharmony_ci char strTime[DEFAULT_TIME_SIZE] = ""; 4943e5483f6Sopenharmony_ci int64_t times = time / MSEC_TO_SEC; 4953e5483f6Sopenharmony_ci auto tm = localtime(×); 4963e5483f6Sopenharmony_ci if (tm == nullptr) { 4973e5483f6Sopenharmony_ci return ""; 4983e5483f6Sopenharmony_ci } 4993e5483f6Sopenharmony_ci (void)strftime(strTime, sizeof(strTime), format.c_str(), tm); 5003e5483f6Sopenharmony_ci return strTime; 5013e5483f6Sopenharmony_ci} 5023e5483f6Sopenharmony_ci 5033e5483f6Sopenharmony_cistatic const int URL_DECODE_DOUBLE = 2; 5043e5483f6Sopenharmony_cistring RingtoneFileUtils::UrlDecode(const string &src) 5053e5483f6Sopenharmony_ci{ 5063e5483f6Sopenharmony_ci string ret; 5073e5483f6Sopenharmony_ci char ch; 5083e5483f6Sopenharmony_ci int tmpNum; 5093e5483f6Sopenharmony_ci for (size_t i = 0; i < src.length(); i++) { 5103e5483f6Sopenharmony_ci if (src[i]=='%') { 5113e5483f6Sopenharmony_ci if (sscanf_s(src.substr(i + 1, URL_DECODE_DOUBLE).c_str(), "%x", &tmpNum) == -1) { 5123e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Not a valid url: %{private}s", src.c_str()); 5133e5483f6Sopenharmony_ci return src; 5143e5483f6Sopenharmony_ci } 5153e5483f6Sopenharmony_ci ch = static_cast<char>(tmpNum); 5163e5483f6Sopenharmony_ci ret += ch; 5173e5483f6Sopenharmony_ci i = i + URL_DECODE_DOUBLE; 5183e5483f6Sopenharmony_ci } else { 5193e5483f6Sopenharmony_ci ret += src[i]; 5203e5483f6Sopenharmony_ci } 5213e5483f6Sopenharmony_ci } 5223e5483f6Sopenharmony_ci return ret; 5233e5483f6Sopenharmony_ci} 5243e5483f6Sopenharmony_ci 5253e5483f6Sopenharmony_cistatic int32_t MkdirRecursive(const string &path, size_t start) 5263e5483f6Sopenharmony_ci{ 5273e5483f6Sopenharmony_ci RINGTONE_DEBUG_LOG("start pos %{public}zu", start); 5283e5483f6Sopenharmony_ci size_t end = path.find("/", start + 1); 5293e5483f6Sopenharmony_ci 5303e5483f6Sopenharmony_ci string subDir = ""; 5313e5483f6Sopenharmony_ci if (end == std::string::npos) { 5323e5483f6Sopenharmony_ci if (start + 1 == path.size()) { 5333e5483f6Sopenharmony_ci RINGTONE_DEBUG_LOG("path size=%zu", path.size()); 5343e5483f6Sopenharmony_ci } else { 5353e5483f6Sopenharmony_ci subDir = path.substr(start + 1, path.size() - start - 1); 5363e5483f6Sopenharmony_ci } 5373e5483f6Sopenharmony_ci } else { 5383e5483f6Sopenharmony_ci subDir = path.substr(start + 1, end - start - 1); 5393e5483f6Sopenharmony_ci } 5403e5483f6Sopenharmony_ci 5413e5483f6Sopenharmony_ci if (subDir.size() == 0) { 5423e5483f6Sopenharmony_ci return E_SUCCESS; 5433e5483f6Sopenharmony_ci } else { 5443e5483f6Sopenharmony_ci string real = path.substr(0, start + subDir.size() + 1); 5453e5483f6Sopenharmony_ci mode_t mask = umask(0); 5463e5483f6Sopenharmony_ci int result = mkdir(real.c_str(), MODE_RWX_USR_GRP); 5473e5483f6Sopenharmony_ci if (result == 0) { 5483e5483f6Sopenharmony_ci RINGTONE_INFO_LOG("mkdir %{public}s successfully", real.c_str()); 5493e5483f6Sopenharmony_ci } else { 5503e5483f6Sopenharmony_ci RINGTONE_INFO_LOG("mkdir %{public}s failed, errno is %{public}d", real.c_str(), errno); 5513e5483f6Sopenharmony_ci } 5523e5483f6Sopenharmony_ci umask(mask); 5533e5483f6Sopenharmony_ci } 5543e5483f6Sopenharmony_ci if (end == std::string::npos) { 5553e5483f6Sopenharmony_ci return E_SUCCESS; 5563e5483f6Sopenharmony_ci } 5573e5483f6Sopenharmony_ci 5583e5483f6Sopenharmony_ci return MkdirRecursive(path, end); 5593e5483f6Sopenharmony_ci} 5603e5483f6Sopenharmony_ci 5613e5483f6Sopenharmony_ciint32_t RingtoneFileUtils::CreatePreloadFolder(const string &path) 5623e5483f6Sopenharmony_ci{ 5633e5483f6Sopenharmony_ci RINGTONE_DEBUG_LOG("start"); 5643e5483f6Sopenharmony_ci if (access(path.c_str(), F_OK) == 0) { 5653e5483f6Sopenharmony_ci RINGTONE_DEBUG_LOG("dir is existing"); 5663e5483f6Sopenharmony_ci return E_SUCCESS; 5673e5483f6Sopenharmony_ci } 5683e5483f6Sopenharmony_ci 5693e5483f6Sopenharmony_ci auto start = path.find(RINGTONE_CUSTOMIZED_BASE_PATH); 5703e5483f6Sopenharmony_ci if (start == string::npos) { 5713e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("base dir is wrong"); 5723e5483f6Sopenharmony_ci return E_ERR; 5733e5483f6Sopenharmony_ci } 5743e5483f6Sopenharmony_ci 5753e5483f6Sopenharmony_ci return MkdirRecursive(path, start + RINGTONE_CUSTOMIZED_BASE_PATH.size()); 5763e5483f6Sopenharmony_ci} 5773e5483f6Sopenharmony_ci 5783e5483f6Sopenharmony_civoid RingtoneFileUtils::CreateRingtoneDir() 5793e5483f6Sopenharmony_ci{ 5803e5483f6Sopenharmony_ci static const vector<string> userPreloadDirs = { 5813e5483f6Sopenharmony_ci { RINGTONE_CUSTOMIZED_ALARM_PATH }, { RINGTONE_CUSTOMIZED_RINGTONE_PATH }, 5823e5483f6Sopenharmony_ci { RINGTONE_CUSTOMIZED_NOTIFICATIONS_PATH } 5833e5483f6Sopenharmony_ci }; 5843e5483f6Sopenharmony_ci 5853e5483f6Sopenharmony_ci for (const auto &dir: userPreloadDirs) { 5863e5483f6Sopenharmony_ci if (CreatePreloadFolder(dir) != E_SUCCESS) { 5873e5483f6Sopenharmony_ci RINGTONE_INFO_LOG("scan failed on dir %{public}s", dir.c_str()); 5883e5483f6Sopenharmony_ci continue; 5893e5483f6Sopenharmony_ci } 5903e5483f6Sopenharmony_ci } 5913e5483f6Sopenharmony_ci} 5923e5483f6Sopenharmony_ci 5933e5483f6Sopenharmony_ciint32_t RingtoneFileUtils::MoveDirectory(const std::string &srcDir, const std::string &dstDir) 5943e5483f6Sopenharmony_ci{ 5953e5483f6Sopenharmony_ci if (access(srcDir.c_str(), F_OK) != 0) { 5963e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("access srcDir failed, errno is %{public}d", errno); 5973e5483f6Sopenharmony_ci return E_FAIL; 5983e5483f6Sopenharmony_ci } 5993e5483f6Sopenharmony_ci if (access(dstDir.c_str(), F_OK) != 0) { 6003e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("access dstDir failed, errno is %{public}d", errno); 6013e5483f6Sopenharmony_ci return E_FAIL; 6023e5483f6Sopenharmony_ci } 6033e5483f6Sopenharmony_ci int ret = E_SUCCESS; 6043e5483f6Sopenharmony_ci for (const auto &dirEntry : std::filesystem::directory_iterator{ srcDir }) { 6053e5483f6Sopenharmony_ci std::string srcFilePath = dirEntry.path(); 6063e5483f6Sopenharmony_ci std::string tmpFilePath = srcFilePath; 6073e5483f6Sopenharmony_ci std::string dstFilePath = tmpFilePath.replace(0, srcDir.length(), dstDir); 6083e5483f6Sopenharmony_ci if (!MoveFile(srcFilePath, dstFilePath)) { 6093e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Move file failed, errno is %{public}d", errno); 6103e5483f6Sopenharmony_ci ret = E_FAIL; 6113e5483f6Sopenharmony_ci } 6123e5483f6Sopenharmony_ci } 6133e5483f6Sopenharmony_ci return ret; 6143e5483f6Sopenharmony_ci} 6153e5483f6Sopenharmony_ci 6163e5483f6Sopenharmony_civoid RingtoneFileUtils::AccessRingtoneDir() 6173e5483f6Sopenharmony_ci{ 6183e5483f6Sopenharmony_ci if (access(RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str(), F_OK) != 0) { 6193e5483f6Sopenharmony_ci CreateRingtoneDir(); 6203e5483f6Sopenharmony_ci return; 6213e5483f6Sopenharmony_ci } 6223e5483f6Sopenharmony_ci struct stat fileStat; 6233e5483f6Sopenharmony_ci if (stat(RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str(), &fileStat) != 0) { 6243e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("stat dir failed, errno is %{public}d", errno); 6253e5483f6Sopenharmony_ci return; 6263e5483f6Sopenharmony_ci } 6273e5483f6Sopenharmony_ci // 检查组的写权限 6283e5483f6Sopenharmony_ci if ((fileStat.st_mode & S_IWGRP) != 0) { 6293e5483f6Sopenharmony_ci return; 6303e5483f6Sopenharmony_ci } 6313e5483f6Sopenharmony_ci if (IsEmptyFolder(RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str())) { 6323e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("The directory is empty and lacks group write permission."); 6333e5483f6Sopenharmony_ci if (DeleteFile(RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str())) { 6343e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("DeleteFile denied, errCode: %{public}d", errno); 6353e5483f6Sopenharmony_ci } 6363e5483f6Sopenharmony_ci CreateRingtoneDir(); 6373e5483f6Sopenharmony_ci } else { //rename and move file 6383e5483f6Sopenharmony_ci if (MoveFile(RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str(), 6393e5483f6Sopenharmony_ci RINGTONE_CUSTOMIZED_BASE_RINGTONETMP_PATH.c_str())) { 6403e5483f6Sopenharmony_ci if (CreatePreloadFolder(RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str()) != E_SUCCESS) { 6413e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Create Ringtone dir failed, errno is %{public}d", errno); 6423e5483f6Sopenharmony_ci //restore dir 6433e5483f6Sopenharmony_ci MoveFile(RINGTONE_CUSTOMIZED_BASE_RINGTONETMP_PATH.c_str(), 6443e5483f6Sopenharmony_ci RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str()); 6453e5483f6Sopenharmony_ci return; 6463e5483f6Sopenharmony_ci } 6473e5483f6Sopenharmony_ci if (MoveDirectory(RINGTONE_CUSTOMIZED_BASE_RINGTONETMP_PATH.c_str(), 6483e5483f6Sopenharmony_ci RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str()) != E_SUCCESS) { 6493e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Move dir failed, errno is %{public}d", errno); 6503e5483f6Sopenharmony_ci CreateRingtoneDir(); 6513e5483f6Sopenharmony_ci return; 6523e5483f6Sopenharmony_ci } 6533e5483f6Sopenharmony_ci if (DeleteFile(RINGTONE_CUSTOMIZED_BASE_RINGTONETMP_PATH.c_str())) { 6543e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("DeleteFile denied, errCode: %{public}d", errno); 6553e5483f6Sopenharmony_ci } 6563e5483f6Sopenharmony_ci } else { 6573e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Move Ringtone dir failed, errno is %{public}d", errno); 6583e5483f6Sopenharmony_ci } 6593e5483f6Sopenharmony_ci } 6603e5483f6Sopenharmony_ci return; 6613e5483f6Sopenharmony_ci} 6623e5483f6Sopenharmony_ci 6633e5483f6Sopenharmony_cistring RingtoneFileUtils::GetFileExtension(const string &path) 6643e5483f6Sopenharmony_ci{ 6653e5483f6Sopenharmony_ci if (!path.empty()) { 6663e5483f6Sopenharmony_ci size_t dotIndex = path.rfind("."); 6673e5483f6Sopenharmony_ci if (dotIndex != string::npos) { 6683e5483f6Sopenharmony_ci return path.substr(dotIndex + 1); 6693e5483f6Sopenharmony_ci } 6703e5483f6Sopenharmony_ci } 6713e5483f6Sopenharmony_ci 6723e5483f6Sopenharmony_ci RINGTONE_ERR_LOG("Failed to obtain file extension because given pathname is empty"); 6733e5483f6Sopenharmony_ci return ""; 6743e5483f6Sopenharmony_ci} 6753e5483f6Sopenharmony_ci} // namespace Media 6763e5483f6Sopenharmony_ci} // namespace OHOS 677