15bebb993Sopenharmony_ci/* 25bebb993Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 35bebb993Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 45bebb993Sopenharmony_ci * you may not use this file except in compliance with the License. 55bebb993Sopenharmony_ci * You may obtain a copy of the License at 65bebb993Sopenharmony_ci * 75bebb993Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 85bebb993Sopenharmony_ci * 95bebb993Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 105bebb993Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 115bebb993Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 125bebb993Sopenharmony_ci * See the License for the specific language governing permissions and 135bebb993Sopenharmony_ci * limitations under the License. 145bebb993Sopenharmony_ci */ 155bebb993Sopenharmony_ci 165bebb993Sopenharmony_ci#include "fileio_native.h" 175bebb993Sopenharmony_ci 185bebb993Sopenharmony_ci#include <sys/xattr.h> 195bebb993Sopenharmony_ci 205bebb993Sopenharmony_ci#include "file_uri.h" 215bebb993Sopenharmony_ci#include "filemgmt_libhilog.h" 225bebb993Sopenharmony_ci 235bebb993Sopenharmony_ciusing namespace OHOS; 245bebb993Sopenharmony_ciusing namespace OHOS::FileManagement; 255bebb993Sopenharmony_ci 265bebb993Sopenharmony_cinamespace { 275bebb993Sopenharmony_ci enum Location { 285bebb993Sopenharmony_ci LOCAL = 1, 295bebb993Sopenharmony_ci CLOUD = 2, 305bebb993Sopenharmony_ci LOCAL_AND_CLOUD = 3 315bebb993Sopenharmony_ci }; 325bebb993Sopenharmony_ci 335bebb993Sopenharmony_ci const size_t MAX_ATTR_NAME = 64; 345bebb993Sopenharmony_ci const std::string CLOUD_LOCATION_ATTR = "user.cloud.location"; 355bebb993Sopenharmony_ci 365bebb993Sopenharmony_ci bool CheckLocation(const std::string &location) 375bebb993Sopenharmony_ci { 385bebb993Sopenharmony_ci if (!std::all_of(location.begin(), location.end(), ::isdigit)) { 395bebb993Sopenharmony_ci return false; 405bebb993Sopenharmony_ci } 415bebb993Sopenharmony_ci int fileLocation = atoi(location.c_str()); 425bebb993Sopenharmony_ci if (fileLocation < Location::LOCAL || fileLocation > Location::LOCAL_AND_CLOUD) { 435bebb993Sopenharmony_ci return false; 445bebb993Sopenharmony_ci } 455bebb993Sopenharmony_ci return true; 465bebb993Sopenharmony_ci } 475bebb993Sopenharmony_ci 485bebb993Sopenharmony_ci int GetLocationFromPath(const std::string &path) 495bebb993Sopenharmony_ci { 505bebb993Sopenharmony_ci std::unique_ptr<char[]> value = std::make_unique<char[]>(MAX_ATTR_NAME); 515bebb993Sopenharmony_ci if (value == nullptr) { 525bebb993Sopenharmony_ci HILOGE("Failed to request heap memory"); 535bebb993Sopenharmony_ci return -ENOMEM; 545bebb993Sopenharmony_ci } 555bebb993Sopenharmony_ci ssize_t size = 0; 565bebb993Sopenharmony_ci size = getxattr(path.c_str(), CLOUD_LOCATION_ATTR.c_str(), value.get(), MAX_ATTR_NAME); 575bebb993Sopenharmony_ci Location defaultLocation = LOCAL; 585bebb993Sopenharmony_ci if (size <= 0) { 595bebb993Sopenharmony_ci if (errno == ENOENT) { 605bebb993Sopenharmony_ci return -ENOENT; 615bebb993Sopenharmony_ci } else if (errno != ENODATA && errno != EOPNOTSUPP) { 625bebb993Sopenharmony_ci HILOGE("Failed to getxattr, errno: %{public}d", errno); 635bebb993Sopenharmony_ci } 645bebb993Sopenharmony_ci return static_cast<int>(defaultLocation); 655bebb993Sopenharmony_ci } 665bebb993Sopenharmony_ci std::string location = std::string(value.get(), static_cast<size_t>(size)); 675bebb993Sopenharmony_ci if (!CheckLocation(location)) { 685bebb993Sopenharmony_ci HILOGE("Invalid location from getxattr, location: %{public}s", location.c_str()); 695bebb993Sopenharmony_ci return static_cast<int>(defaultLocation); 705bebb993Sopenharmony_ci } 715bebb993Sopenharmony_ci defaultLocation = static_cast<Location>(atoi(location.c_str())); 725bebb993Sopenharmony_ci return static_cast<int>(defaultLocation); 735bebb993Sopenharmony_ci } 745bebb993Sopenharmony_ci} 755bebb993Sopenharmony_ci 765bebb993Sopenharmony_ci__attribute__((visibility("default"))) int GetFileLocation(char *uri, int uriLength, int *location) 775bebb993Sopenharmony_ci{ 785bebb993Sopenharmony_ci if (uri == nullptr || location == nullptr || uriLength <= 0 || uriLength > PATH_MAX) { 795bebb993Sopenharmony_ci return -EINVAL; 805bebb993Sopenharmony_ci } 815bebb993Sopenharmony_ci std::string uriStr(uri, uriLength); 825bebb993Sopenharmony_ci AppFileService::ModuleFileUri::FileUri fileUri(uriStr); 835bebb993Sopenharmony_ci int ret = GetLocationFromPath(fileUri.GetRealPath()); 845bebb993Sopenharmony_ci if (ret > 0) { 855bebb993Sopenharmony_ci *location = ret; 865bebb993Sopenharmony_ci return 0; 875bebb993Sopenharmony_ci } 885bebb993Sopenharmony_ci return ret; 895bebb993Sopenharmony_ci} 90