SVACE: HEAP_LEAK, correct size in strncpy
[platform/core/security/tef-simulator.git] / ssflib / dep / swdss / source / file_op.cpp
1 /**
2  * Copyright (c) 2013-2017 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include "file_op.h"
19 #include "Osal.h"
20 #include <errno.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stddef.h>
24 #include <unistd.h>
25
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/wait.h>
29
30 #include <pthread.h>
31
32 pthread_mutex_t delLock = PTHREAD_MUTEX_INITIALIZER;
33 pthread_mutex_t createLock = PTHREAD_MUTEX_INITIALIZER;
34
35 using namespace std;
36
37 int file_op::write_file(const char* filename, unsigned char* buffer,
38     unsigned int size) {
39         SLOGI("entering file_op::write_file");
40         if (NULL == buffer) {
41                 return SS_RET_INVALID_PARAM;
42         }
43
44         FILE* file;
45
46         if (is_valid_filename(filename)) {
47                 SLOGD("[%s][%d] NOT valid file : [ %s ]", __FUNCTION__, __LINE__, filename);
48                 return SS_RET_INVALID_PARAM;
49         }
50
51         // create folder if not exist.
52         char base_path[255] = {0};
53         get_base_path(filename, base_path);
54         SLOGI("base_path %s.", base_path);
55         if (!is_folder_exists(base_path)) {
56                 if (0 != create_folder(base_path)) {
57                         return SS_RET_FAIL;
58                 }
59         }
60
61         /* open file */
62         file = fopen(filename, "wb");
63         if (NULL == file) {
64                 SLOGD("[%s][%d] fopen(..) == NULL , Can't open [ %s ] file. ", __FUNCTION__,
65                     __LINE__, filename);
66                 return SS_RET_CANT_FIND_REQUESTED_DATA;
67         }
68
69         if (size != fwrite(buffer, 1, size, file)) {
70                 SLOGD("[%s][%d]!!!DIFFERENT!!!", __FUNCTION__, __LINE__);
71                 fclose(file);
72                 return SS_RET_FAIL;
73         }
74
75         fflush(file);
76
77         //sync(fileno(file));   // sync blocked
78
79         fclose(file);
80
81         return SS_RET_SUCCESS;
82 }
83
84 int file_op::read_file(const char* filename, unsigned char** buffer,
85     unsigned int& size) {
86         SLOGI("Entering file_op::read_file...");
87         FILE* file;
88         long fLen;
89         *buffer = NULL;
90         size = 0;
91
92         if (is_valid_filename(filename)) {
93                 SLOGD("[%s][%d] NOT valid file : [ %s ]", __FUNCTION__, __LINE__, filename);
94                 return SS_RET_INVALID_PARAM;
95         }
96
97         /* open file */
98         file = fopen(filename, "rb");
99         if (NULL == file) {
100                 SLOGD("[%s][%d] fopen(..) == NULL , Can't open [ %s ] file. ", __FUNCTION__,
101                     __LINE__, filename);
102                 return SS_RET_CANT_FIND_REQUESTED_DATA;
103         }
104
105         /* computing file size */
106         if(fseek(file, 0, SEEK_END) != 0){
107         fclose(file);
108         return SS_RET_FAIL;
109     }
110     fLen = ftell(file);
111         if (fLen > 0) {
112                 size = fLen;
113         }
114     if( fseek(file, 0, SEEK_SET) != 0){
115         fclose(file);
116         return SS_RET_FAIL;
117     }
118
119         /* allocating data buffer with enough size */
120         *buffer = (unsigned char *)OsaMalloc(size);
121         if (!(*buffer)) {
122                 SLOGD("[%s][%d] Can't malloc pBuffer to 'fread'. ", __FUNCTION__, __LINE__);
123                 fclose(file);
124                 return SS_RET_MALLOC_FAILED;
125         }
126
127         /* reading data from file */
128         if (size != fread(*buffer, size, 1, file)) {
129                 SLOGD("[%s][%d] Read size is not equal to required size %d.", __FUNCTION__,
130                     __LINE__, size);
131         }
132
133         /* closing file */
134         fclose(file);
135
136         SLOGI("[%s][%d] File read successfully", __FUNCTION__, __LINE__);
137         return SS_RET_SUCCESS;
138 }
139
140 int file_op::remove_file(const char* filename) {
141         SLOGI("[%s][%d] Entering file_op::remove_file", __FUNCTION__, __LINE__);
142     pthread_mutex_lock(&delLock);
143         bool ret = is_file_exists(filename);
144         if (ret) {
145                 ret = remove(filename);
146                 if (0 != ret) {
147                         SLOGD("[%s][%d] remove , nRet : %d , file [ %s ] not removed",
148                             __FUNCTION__, __LINE__, ret, filename);
149                         pthread_mutex_unlock(&delLock);
150                         return SS_RET_FAIL;
151                 }
152         } else {
153                 SLOGD("[%s][%d] access not ok , nRet : %d , There's NO file [ %s ] ",
154                     __FUNCTION__, __LINE__, ret, filename);
155                 pthread_mutex_unlock(&delLock);
156                 return SS_RET_CANT_FIND_REQUESTED_DATA;
157         }
158     pthread_mutex_unlock(&delLock);
159         SLOGI("[%s][%d] Succeed to remove file...", __FUNCTION__, __LINE__);
160
161         return SS_RET_SUCCESS;
162 }
163
164 int file_op::is_valid_filename(const char* filename) {
165         // path shall not contain any "strange" characters
166         const char* validated_path = strpbrk(filename, "&;`'\"|*?~<>^()[]{}$\n \r");
167         if (validated_path != NULL) {
168                 SLOGD(
169                     "[%s][%d] There are some forbidden charactors in path.(&;`'\"|*?~<>^()[]{}$\n \r) ",
170                     __FUNCTION__, __LINE__);
171                 return SS_RET_INVALID_PARAM;
172         }
173
174         return SS_RET_SUCCESS;
175 }
176
177 int file_op::create_folder(const char* folder) {
178         SLOGI("[%s][%d] START", __FUNCTION__, __LINE__);
179
180         char base_p[256] = {0};
181         get_base_path(folder, base_p);
182         if (!is_folder_exists(base_p)) {
183                 if (0 != create_folder(base_p)) {
184                         SLOGE("Failed to create folder %s.", base_p);
185                         return SS_RET_FAIL;
186                 }
187         }
188
189         uint32_t result = SS_RET_SUCCESS;
190         struct stat st;
191         memset(&st, 0, sizeof(st));
192     pthread_mutex_lock(&createLock);
193         int res = stat(folder, &st);
194
195         if (res == -1) {
196                 res = mkdir(folder, S_IRWXU);
197                 if (0 != res) {
198                         result = SS_RET_FAIL;
199                         SLOGE("Failed to create folder %s.", folder);
200                 }
201                 //sync();
202         } else if (!(S_ISDIR(st.st_mode))) {
203                 result = SS_RET_FAIL;
204         }
205     pthread_mutex_unlock(&createLock);
206
207         SLOGI("[%s][%d] END", __FUNCTION__, __LINE__);
208
209         return result;
210 }
211
212 int file_op::remove_folder(const char* folder) {
213         SLOGI("[%s][%d] START", __FUNCTION__, __LINE__);
214
215         rmdir(folder);
216
217         SLOGI("[%s][%d] END", __FUNCTION__, __LINE__);
218         return SS_RET_SUCCESS;
219 }
220
221 bool file_op::is_folder_exists(const char* folder) {
222         return is_file_exists(folder);
223 }
224
225 bool file_op::is_file_exists(const char* file) {
226         struct stat st;
227         memset(&st, 0, sizeof(st));
228         int res = stat(file, &st);
229         return (res != -1);
230 }
231
232 void file_op::get_base_path(const char* filename, char* base_path) {
233         for (int i = strlen(filename) - 1; i >= 0; --i) {
234                 if ('/' == filename[i]) {
235                         memcpy(base_path, filename, i);
236                         base_path[i] = '\0';
237                         break;
238                 }
239         }
240 }
241