1 /*
2 * Copyright (C) 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
16 #include "nstackx_util.h"
17 #include "nstackx_timer.h"
18 #include "nstackx_error.h"
19 #include "nstackx_log.h"
20 #include "securec.h"
21
22 #define TAG "nStackXUtil"
23 #define DEFAULT_NEW_PATH_AUTHORITY 0750
24
GetTargetFileSize(const char * dir,uint64_t * size)25 int32_t GetTargetFileSize(const char *dir, uint64_t *size)
26 {
27 struct stat statbuf;
28
29 if (dir == NULL || size == NULL) {
30 LOGE(TAG, "Invalid dir or size");
31 return NSTACKX_EINVAL;
32 }
33
34 if (stat(dir, &statbuf) != 0 || statbuf.st_size < 0) {
35 LOGE(TAG, "stat error: %d", GetErrno());
36 return NSTACKX_EFAILED;
37 }
38
39 *size = (uint64_t)statbuf.st_size;
40 return NSTACKX_EOK;
41 }
42
CheckPathSeprator(const char * path)43 int32_t CheckPathSeprator(const char *path)
44 {
45 if (strlen(path) > 0 && path[strlen(path) - 1] == PATH_SEPARATOR) {
46 return NSTACKX_TRUE;
47 }
48 return NSTACKX_FALSE;
49 }
50
CheckFilenameSeprator(const char * fileName)51 int32_t CheckFilenameSeprator(const char *fileName)
52 {
53 if (strlen(fileName) > 0 && fileName[0] == PATH_SEPARATOR) {
54 return NSTACKX_TRUE;
55 }
56 return NSTACKX_FALSE;
57 }
58
59 /*
60 * return value includes the length of terminator '\0'
61 * return value 0 means the input dir is null or it's last char is PATH_SEPARATOR
62 */
GetFileNameLen(const char * dir)63 uint32_t GetFileNameLen(const char *dir)
64 {
65 int32_t i;
66
67 if (dir == NULL || strlen(dir) < 1 || dir[strlen(dir) - 1] == PATH_SEPARATOR) {
68 LOGE(TAG, "Invalid input param");
69 return 0;
70 }
71
72 int32_t dirLen = (int32_t)strlen(dir);
73 for (i = dirLen - 1; i >= 0; i--) {
74 if (dir[i] == PATH_SEPARATOR) {
75 i++;
76 break;
77 }
78 if (i == 0) {
79 break;
80 }
81 }
82 return (uint32_t)(dirLen + 1 - i);
83 }
84
GetFileName(const char * dir,char * name,uint32_t nameLen)85 int32_t GetFileName(const char *dir, char *name, uint32_t nameLen)
86 {
87 uint32_t fileNameLen, startIdx;
88
89 if (dir == NULL || name == NULL) {
90 LOGE(TAG, "Invalid dir or name");
91 return NSTACKX_EINVAL;
92 }
93
94 fileNameLen = GetFileNameLen(dir);
95 if (fileNameLen == 0 || fileNameLen > nameLen) {
96 LOGE(TAG, "Invalid fileNameLen dir: %s", dir);
97 return NSTACKX_EINVAL;
98 }
99 startIdx = (uint32_t)(strlen(dir) + 1 - fileNameLen);
100 if (strcpy_s(name, nameLen, dir + startIdx) != EOK) {
101 LOGE(TAG, "strcpy_s name error");
102 return NSTACKX_EFAILED;
103 }
104 return NSTACKX_EOK;
105 }
106
IsAccessiblePath(const char * pathName,int32_t mode,uint32_t fileType)107 uint8_t IsAccessiblePath(const char *pathName, int32_t mode, uint32_t fileType)
108 {
109 struct stat statbuf;
110 if (pathName == NULL) {
111 LOGE(TAG, "invalid input");
112 return NSTACKX_FALSE;
113 }
114 if (stat(pathName, &statbuf) != 0) {
115 LOGE(TAG, "can't get file stat.error: %d", GetErrno());
116 return NSTACKX_FALSE;
117 }
118 if (((statbuf.st_mode) & S_IFMT) != fileType) {
119 LOGE(TAG, "this path name is not target file type");
120 return NSTACKX_FALSE;
121 }
122
123 if (access(pathName, F_OK) != 0) {
124 return NSTACKX_FALSE;
125 }
126
127 if (access(pathName, mode) != 0) {
128 return NSTACKX_FALSE;
129 }
130 return NSTACKX_TRUE;
131 }
132
IsExistingFile(const char * fileName)133 uint8_t IsExistingFile(const char *fileName)
134 {
135 if (access(fileName, F_OK) != 0) {
136 return NSTACKX_FALSE;
137 }
138 return NSTACKX_TRUE;
139 }
140
TestAndCreateDirectory(const char * path)141 int32_t TestAndCreateDirectory(const char *path)
142 {
143 uint32_t len, i;
144 char *tmp = NULL;
145 int32_t ret;
146
147 if (path == NULL || strlen(path) == 0) {
148 return NSTACKX_EINVAL;
149 }
150
151 len = (uint32_t)strlen(path);
152
153 tmp = (char *)calloc(len + 1, sizeof(char));
154 if (tmp == NULL) {
155 LOGE(TAG, "tmp calloc error");
156 return NSTACKX_EFAILED;
157 }
158
159 for (i = 0; i < len; i++) {
160 tmp[i] = path[i];
161 if (tmp[i] != PATH_SEPARATOR) {
162 continue;
163 }
164 if (access(tmp, 0) == -1) {
165 ret = mkdir(tmp, DEFAULT_NEW_PATH_AUTHORITY);
166 if (ret == -1 && errno != EEXIST) {
167 LOGI(TAG, "mkdir failed(%d)", errno);
168 free(tmp);
169 return NSTACKX_EFAILED;
170 }
171 }
172 }
173 free(tmp);
174 return NSTACKX_EOK;
175 }
176
177 #define UCHAR2_TO_UINT16(_buf) (((uint16_t)((_buf)[0]) << 8u) | (uint16_t)((_buf)[1]))
178
IpAddrAnonymousFormat(char * buf,size_t len,const struct sockaddr * addr,size_t addrLen)179 int32_t IpAddrAnonymousFormat(char *buf, size_t len, const struct sockaddr *addr, size_t addrLen)
180 {
181 if (buf == NULL || len == 0 || addr == NULL) {
182 return NSTACKX_EFAILED;
183 }
184
185 int32_t ret = NSTACKX_EFAILED;
186 if (addr->sa_family == AF_INET && addrLen >= sizeof(struct sockaddr_in)) {
187 uint32_t ip4 = ((const struct sockaddr_in *)addr)->sin_addr.s_addr;
188 ret = snprintf_s(buf, len, len - 1, "%hhu.%hhu.%hhu.*",
189 ((uint8_t *)&ip4)[0], ((uint8_t *)&ip4)[1], ((uint8_t *)&ip4)[2]); /* print the first 3 bytes */
190 } else if (addr->sa_family == AF_INET6 && addrLen >= sizeof(struct sockaddr_in6)) {
191 const uint8_t *ip6 = ((const struct sockaddr_in6 *)addr)->sin6_addr.s6_addr;
192 ret = snprintf_s(buf, len, len - 1, "%x:%x:%x*:*:*:*:*:*",
193 UCHAR2_TO_UINT16(ip6), UCHAR2_TO_UINT16(ip6 + 2), ip6[4]); /* print the first 5 bytes */
194 }
195
196 return ret;
197 }
198