19762338dSopenharmony_ci/*
29762338dSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
39762338dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
49762338dSopenharmony_ci * you may not use this file except in compliance with the License.
59762338dSopenharmony_ci * You may obtain a copy of the License at
69762338dSopenharmony_ci *
79762338dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
89762338dSopenharmony_ci *
99762338dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
109762338dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
119762338dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129762338dSopenharmony_ci * See the License for the specific language governing permissions and
139762338dSopenharmony_ci * limitations under the License.
149762338dSopenharmony_ci */
159762338dSopenharmony_ci
169762338dSopenharmony_ci#include <unistd.h>
179762338dSopenharmony_ci#include <cstdlib>
189762338dSopenharmony_ci#include <cstring>
199762338dSopenharmony_ci#include <cerrno>
209762338dSopenharmony_ci#include <dirent.h>
219762338dSopenharmony_ci#include <fcntl.h>
229762338dSopenharmony_ci#include <sys/stat.h>
239762338dSopenharmony_ci#include "log.h"
249762338dSopenharmony_ci#include "libfs.h"
259762338dSopenharmony_ci#include "KernelConstants.h"
269762338dSopenharmony_ciusing namespace std;
279762338dSopenharmony_ci
289762338dSopenharmony_ciint MakeDir(const char *dirname)
299762338dSopenharmony_ci{
309762338dSopenharmony_ci    if (access(dirname, F_OK) == 0) {
319762338dSopenharmony_ci        LOG("dir:%s exists", dirname);
329762338dSopenharmony_ci        return 1;
339762338dSopenharmony_ci    } else {
349762338dSopenharmony_ci        int rt = mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR | S_IRWXG | S_IXOTH);
359762338dSopenharmony_ci        if (rt) {
369762338dSopenharmony_ci            LOG("create dir failed! path=%s, errno=%d:%s", dirname, errno, strerror(errno));
379762338dSopenharmony_ci            return -1;
389762338dSopenharmony_ci        }
399762338dSopenharmony_ci    }
409762338dSopenharmony_ci    return 0;
419762338dSopenharmony_ci}
429762338dSopenharmony_ci
439762338dSopenharmony_ciint RemoveDir(const char *dirname)
449762338dSopenharmony_ci{
459762338dSopenharmony_ci    char subDir[MAX_PATH_SIZE];
469762338dSopenharmony_ci    struct stat dirStat = {0};
479762338dSopenharmony_ci
489762338dSopenharmony_ci    if (stat(dirname, &dirStat) < 0) {
499762338dSopenharmony_ci        LOG("get directory stat error, errno=%d:%s", errno, strerror(errno));
509762338dSopenharmony_ci        return -1;
519762338dSopenharmony_ci    }
529762338dSopenharmony_ci
539762338dSopenharmony_ci    if (S_ISDIR(dirStat.st_mode)) {
549762338dSopenharmony_ci        DIR *pDir = opendir(dirname);
559762338dSopenharmony_ci        struct dirent *entry;
569762338dSopenharmony_ci        while ((entry = readdir(pDir))) {
579762338dSopenharmony_ci            std::string fname = entry->d_name;
589762338dSopenharmony_ci            if (!strcmp(fname, ".") || !strcmp(fname, "..")) {
599762338dSopenharmony_ci                continue; // skip . and ..
609762338dSopenharmony_ci            }
619762338dSopenharmony_ci            // MAX_PATH_SIZE is the max length of allowed path string, so it safe to use sprintf here.
629762338dSopenharmony_ci            size_t rt = sprintf_s(subDir, sizeof(subDir), "%s/%s", dirname, fname.c_str());
639762338dSopenharmony_ci            if (rt < 0) {
649762338dSopenharmony_ci                LOG("output failed, dirname=%s, errno=%d:%s", dirname, errno, strerror(errno));
659762338dSopenharmony_ci            }
669762338dSopenharmony_ci            RemoveDir(subDir);   // remove sub dir or file
679762338dSopenharmony_ci        }
689762338dSopenharmony_ci        closedir(pDir);
699762338dSopenharmony_ci        if (rmdir(dirname) == -1) {  // delete empty dir
709762338dSopenharmony_ci            LOG("delete empty directory failed, path=%s, errno=%d:%s", dirname, errno, strerror(errno));
719762338dSopenharmony_ci            return -1;
729762338dSopenharmony_ci        }
739762338dSopenharmony_ci    } else {
749762338dSopenharmony_ci        if (remove(dirname) == -1) {
759762338dSopenharmony_ci            LOG("remove regular file failed, path=%s, errno=%d:%s", dirname, errno, strerror(errno));
769762338dSopenharmony_ci            return -1;
779762338dSopenharmony_ci        }
789762338dSopenharmony_ci    }
799762338dSopenharmony_ci
809762338dSopenharmony_ci    return 0;
819762338dSopenharmony_ci}
829762338dSopenharmony_ci
839762338dSopenharmony_ciint RemoveFile(const char *fpath)
849762338dSopenharmony_ci{
859762338dSopenharmony_ci    if (!remove(fpath)) {
869762338dSopenharmony_ci        LOG("remove file success");
879762338dSopenharmony_ci    } else {
889762338dSopenharmony_ci        LOG("remove file failed! path=%s: errno=%d:%s", fpath, errno, strerror(errno));
899762338dSopenharmony_ci        return -1;
909762338dSopenharmony_ci    }
919762338dSopenharmony_ci    return 0;
929762338dSopenharmony_ci}
939762338dSopenharmony_ci
949762338dSopenharmony_ciint CopyFile(const char *srcFile, const char *dstFile)
959762338dSopenharmony_ci{
969762338dSopenharmony_ci    int rt = 0;
979762338dSopenharmony_ci    FILE *srcFp = fopen(srcFile, "rb");
989762338dSopenharmony_ci    if (srcFp == nullptr) {
999762338dSopenharmony_ci        LOG("Cannot open source file %s: errno=%d,%s \n", srcFile, errno, strerror(errno));
1009762338dSopenharmony_ci        return -1;
1019762338dSopenharmony_ci    }
1029762338dSopenharmony_ci    FILE *dstFp = fopen(dstFile, "wb");
1039762338dSopenharmony_ci    if (dstFp == nullptr) {
1049762338dSopenharmony_ci        LOG("Cannot create dest file %s: errno=%d,%s \n", dstFile, errno, strerror(errno));
1059762338dSopenharmony_ci        fclose(srcFp);
1069762338dSopenharmony_ci        return -1;
1079762338dSopenharmony_ci    }
1089762338dSopenharmony_ci
1099762338dSopenharmony_ci    const int bufSize = 100 * 1024;
1109762338dSopenharmony_ci    char buffer[bufSize];
1119762338dSopenharmony_ci    size_t bytes;
1129762338dSopenharmony_ci    while ((bytes = fread(buffer, 1, sizeof(buffer), srcFp)) > 0) {
1139762338dSopenharmony_ci        if (fwrite(buffer, 1, bytes, dstFp) != bytes) {
1149762338dSopenharmony_ci            LOG("write to dest file failed: errno=%d,%s \n", errno, strerror(errno));
1159762338dSopenharmony_ci            rt = -1;
1169762338dSopenharmony_ci            break;
1179762338dSopenharmony_ci        }
1189762338dSopenharmony_ci    }
1199762338dSopenharmony_ci    if (fclose(srcFp)) {
1209762338dSopenharmony_ci        LOG("close to src file failed: errno=%d,%s \n", errno, strerror(errno));
1219762338dSopenharmony_ci        return -1;
1229762338dSopenharmony_ci    }
1239762338dSopenharmony_ci    if (fclose(dstFp)) {
1249762338dSopenharmony_ci        LOG("close to dst file failed: errno=%d,%s \n", errno, strerror(errno));
1259762338dSopenharmony_ci        return -1;
1269762338dSopenharmony_ci    }
1279762338dSopenharmony_ci    return rt;
1289762338dSopenharmony_ci}
1299762338dSopenharmony_ci
1309762338dSopenharmony_cistring GetCurrentPath()
1319762338dSopenharmony_ci{
1329762338dSopenharmony_ci    static char path1[MAX_PATH_SIZE];
1339762338dSopenharmony_ci    string path = getcwd(path1, MAX_PATH_SIZE);
1349762338dSopenharmony_ci    LOG("current Path = %s,path1=%s", path, path1);
1359762338dSopenharmony_ci    return path1;
1369762338dSopenharmony_ci}
137