1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "init_service_file.h"
16
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <limits.h>
20 #include <string.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24
25 #include "init_log.h"
26 #include "init_service.h"
27 #include "init_utils.h"
28 #include "securec.h"
29
30 #define HOS_FILE_ENV_PREFIX "OHOS_FILE_"
31 #define MAX_FILE_FD_LEN 16
32
CreateFile(ServiceFile * file)33 static int CreateFile(ServiceFile *file)
34 {
35 INIT_CHECK(file != NULL && file->fileName != NULL, return -1);
36 char path[PATH_MAX] = {0};
37 if (realpath(file->fileName, path) == NULL) {
38 INIT_LOGE("Failed realpath err=%d", errno);
39 INIT_ERROR_CHECK(strncpy_s(path, strlen(file->fileName) + 1, file->fileName, strlen(file->fileName)) >= 0,
40 return -1, "Failed strncpy_s err=%d", errno);
41 }
42 INIT_LOGV("File path =%s . file flags =%d, file perm =%u ", path, file->flags, file->perm);
43 if (file->fd >= 0) {
44 close(file->fd);
45 file->fd = -1;
46 }
47 int fd = open(path, file->flags | O_CREAT, file->perm);
48 INIT_ERROR_CHECK(fd >= 0, return -1, "Failed open %s, err=%d ", path, errno);
49 close(fd);
50 INIT_CHECK_ONLY_ELOG(chmod(path, file->perm) >= 0, "Failed chmod err=%d", errno);
51 INIT_CHECK_ONLY_ELOG(chown(path, file->uid, file->gid) >= 0, "Failed chown err=%d", errno);
52 file->fd = open(path, file->flags);
53 return file->fd;
54 }
55
SetFileEnv(int fd,const char * pathName)56 static int SetFileEnv(int fd, const char *pathName)
57 {
58 INIT_ERROR_CHECK(pathName != NULL, return -1, "Invalid fileName");
59 char pubName[PATH_MAX] = { 0 };
60 INIT_ERROR_CHECK(snprintf_s(pubName, sizeof(pubName), sizeof(pubName) - 1,
61 HOS_FILE_ENV_PREFIX "%s", pathName) >= 0, return -1, "Failed snprintf_s err=%d", errno);
62 INIT_ERROR_CHECK(StringReplaceChr(pubName, '/', '_') >= 0, return -1, "Failed StringReplaceChr");
63 char val[MAX_FILE_FD_LEN] = { 0 };
64 INIT_ERROR_CHECK(snprintf_s(val, sizeof(val), sizeof(val) - 1, "%d", fd) >= 0, return -1,
65 "Failed snprintf_s err=%d", errno);
66 int ret = setenv(pubName, val, 1);
67 INIT_ERROR_CHECK(ret >= 0, return -1, "Failed setenv err=%d ", errno);
68 fcntl(fd, F_SETFD, 0);
69 return 0;
70 }
71
CreateServiceFile(Service * service)72 int CreateServiceFile(Service *service)
73 {
74 INIT_CHECK(service != NULL, return INIT_EPARAMETER);
75 ServiceFile *tmpFile = service->fileCfg;
76 int ret = 0;
77 while (tmpFile != NULL) {
78 int fd = CreateFile(tmpFile);
79 if (fd < 0) {
80 ret++;
81 INIT_LOGE("Service error %d %s, failed to create file", errno, service->name, tmpFile->fileName);
82 tmpFile = tmpFile->next;
83 continue;
84 }
85 if (SetFileEnv(fd, tmpFile->fileName) != 0) {
86 ret++;
87 INIT_LOGE("Service error %d %s, failed to set env for file", errno, service->name, tmpFile->fileName);
88 }
89 tmpFile = tmpFile->next;
90 }
91 return ret > 0 ? INIT_EFILE : 0;
92 }
93
CloseServiceFile(ServiceFile * fileOpt)94 void CloseServiceFile(ServiceFile *fileOpt)
95 {
96 INIT_CHECK(fileOpt != NULL, return);
97 ServiceFile *tmpFileOpt = fileOpt;
98 while (tmpFileOpt != NULL) {
99 ServiceFile *tmp = tmpFileOpt;
100 if (tmp->fd >= 0) {
101 close(tmp->fd);
102 tmp->fd = -1;
103 }
104 tmpFileOpt = tmpFileOpt->next;
105 }
106 return;
107 }
108