Tizen 2.1 base
[platform/framework/web/download-provider.git] / agent / download-agent-utils.c
1 /*
2  * Copyright (c) 2012 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 #include <sys/vfs.h>
18 #include <sys/stat.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <time.h>
22 #include <glib.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25 #include <errno.h>
26
27 #include "download-agent-client-mgr.h"
28 #include "download-agent-debug.h"
29 #include "download-agent-dl-mgr.h"
30 #include "download-agent-file.h"
31 #include "download-agent-http-misc.h"
32 #include "download-agent-mime-util.h"
33 #include "download-agent-utils.h"
34 #include "download-agent-plugin-conf.h"
35 #include "download-agent-dl-info-util.h"
36
37 #define DA_HTTP_HEADER_CONTENT_TYPE             "Content-Type"
38 #define DA_HTTP_HEADER_CONTENT_LENGTH   "Content-Length"
39 #define DA_FILE_NUMBER_LIMIT                            (1024*1024)
40
41 typedef struct _da_descriptor_mime_table_t {
42         char *content_type;
43         da_mime_type_id_t mime_type;
44 } da_descriptor_mime_table_t;
45
46 da_descriptor_mime_table_t
47         descriptor_mime_table[] = {
48                 {"", DA_MIME_TYPE_NONE},
49                 /* DRM1.0 */
50                 {"application/vnd.oma.drm.message",
51                                 DA_MIME_TYPE_DRM1_MESSATE}, /* drm1.0 FL.CD*/
52                 {"", DA_MIME_TYPE_END}};
53
54 void get_random_number(int *out_num)
55 {
56         int temp = DA_INVALID_ID;
57         unsigned int seed = (unsigned)time(0);
58
59         temp = (int)(rand_r(&seed) % 100 + 1.0);
60         *out_num = temp;
61 }
62
63 da_result_t get_extension_from_mime_type(char *mime_type, char **extension)
64 {
65         da_result_t ret = DA_RESULT_OK;
66         char *ext = DA_NULL;
67
68         DA_LOG_FUNC_START(Default);
69         if (DA_NULL == mime_type || DA_NULL == extension) {
70                 DA_LOG_ERR(Default,"received mime_type is null");
71                 ret = DA_ERR_INVALID_ARGUMENT;
72                 goto ERR;
73         }
74         DA_LOG(Default,"input mime type = %s", mime_type);
75         if (DA_RESULT_OK != (ret = da_mime_get_ext_name(mime_type, &ext))) {
76                 DA_LOG_ERR(Default,"can't find proper extension!");
77                 goto ERR;
78         }
79         *extension = ext;
80         DA_LOG(Default,"found extension = %s", *extension);
81
82 ERR:
83         return ret;
84 }
85
86 int read_data_from_file(char *file, char **out_buffer)
87 {
88         FILE *fd;
89         unsigned long long file_size = -1;
90         char *buffer = NULL;
91         int buffer_len = 0;
92         size_t read_len = 0;
93
94         *out_buffer = NULL;
95
96         if (!file)
97                 return 0;
98
99         /* open file with "rb", because fread() handles the file as binary mode */
100         fd = fopen(file, "rb");
101         if (!fd) {
102                 DA_LOG_ERR(FileManager,"File open err! received file path = [%s]", file);
103                 return 0;
104         }
105
106         get_file_size(file, &file_size);
107         if (file_size <= 0) {
108                 DA_LOG_ERR(FileManager,"file size is [%llu]", file_size);
109                 fclose(fd);
110                 return 0;
111         }
112
113         /* A guide from www.securecoding.cert.org
114          *    : FIO17-C. Do not rely on an ending null character when using fread()
115          *
116          *  buffer is initialized with null through calloc(), so, it is always null-terminated even if fread() failed.
117          *  allocate memory one more byte to ensure null-terminated even if the file is not null-terminated.
118          */
119         buffer_len = sizeof(char) * file_size;
120         buffer = (char *)calloc(1, buffer_len + 1);
121         if (buffer) {
122                 read_len = fread(buffer, sizeof(char), file_size, fd);
123                 if (read_len == file_size) {
124                         *out_buffer = buffer;
125                 } else {
126                         DA_LOG_ERR(FileManager,"File Read Not Complete read length = %d", read_len);
127                         free(buffer);
128                         buffer = NULL;
129                         buffer_len = 0;
130                 }
131         } else {
132                 buffer_len = 0;
133         }
134
135         fclose(fd);
136
137         return buffer_len;
138 }
139
140 da_result_t get_available_memory(
141         da_storage_type_t storage_type,
142         da_storage_size_t *avail_memory)
143 {
144         da_result_t ret = DA_RESULT_OK;
145         int fs_ret = 0;
146         struct statfs filesys_info = {0, };
147         char *default_install_dir = NULL;
148
149         DA_LOG_FUNC_START(Default);
150
151         if (!avail_memory)
152                 return DA_ERR_INVALID_ARGUMENT;
153
154         ret = get_default_install_dir(&default_install_dir);
155
156         if (ret == DA_RESULT_OK && default_install_dir) {
157                 fs_ret = statfs(default_install_dir, &filesys_info);
158         } else {
159                 return DA_ERR_FAIL_TO_ACCESS_STORAGE;
160         }
161
162         if (fs_ret != 0) {
163                 DA_LOG_ERR(Default,"Phone file path :statfs error - [%d]", errno);
164                 free(default_install_dir);
165                 return DA_ERR_INVALID_INSTALL_PATH;
166         }
167
168         avail_memory->b_available = filesys_info.f_bavail;
169         avail_memory->b_size = filesys_info.f_bsize;
170
171         DA_LOG(Default, "Memory type : %d", storage_type);
172         DA_LOG_VERBOSE(Default, "Available Memory(f_bavail) : %lu", filesys_info.f_bavail);
173         DA_LOG_VERBOSE(Default, "Available Memory(f_bsize) : %d", filesys_info.f_bsize);
174         DA_LOG(Default, "Available Memory(kbytes) : %lu", (filesys_info.f_bavail/1024)*filesys_info.f_bsize);
175
176         free(default_install_dir);
177         return DA_RESULT_OK;
178 }
179
180 da_mime_type_id_t get_mime_type_id(char *content_type)
181 {
182         int i = 0;
183
184         DA_LOG_FUNC_START(Default);
185
186         DA_LOG(Default,"received content_type = %s", content_type);
187
188         if (content_type == NULL) {
189                 DA_LOG_ERR(Default, "No Mime Type\n");
190                 return DA_MIME_TYPE_NONE;
191         }
192
193         while(descriptor_mime_table[i].mime_type != DA_MIME_TYPE_END)
194         {
195                 if (!strcmp(descriptor_mime_table[i].content_type, content_type)) {
196                         break;
197                 }
198                 i++;
199         }
200         DA_LOG(Default, "dd mime type check: index[%d] type[%d]", i, descriptor_mime_table[i].mime_type);
201         return descriptor_mime_table[i].mime_type;
202 }
203
204
205
206 da_bool_t is_valid_url(const char *url, da_result_t *err_code)
207 {
208         da_result_t ret = DA_RESULT_OK;
209         da_bool_t b_ret = DA_FALSE;
210
211         int wanted_str_len = 0;
212         char *wanted_str = NULL;
213         char *wanted_str_start = NULL;
214         char *wanted_str_end = NULL;
215
216         if ((DA_NULL == url) || (1 > strlen(url))) {
217                 ret = DA_ERR_INVALID_URL;
218                 goto ERR;
219         }
220
221         wanted_str_start = (char*)url;
222         wanted_str_end = strstr(url, "://");
223         if (!wanted_str_end) {
224                 DA_LOG_ERR(Default,"No protocol on this url");
225                 ret = DA_ERR_INVALID_URL;
226                 goto ERR;
227         }
228
229         wanted_str_len = wanted_str_end - wanted_str_start;
230         wanted_str = (char*)calloc(1, wanted_str_len + 1);
231         if (!wanted_str) {
232                 DA_LOG_ERR(Default,"DA_ERR_FAIL_TO_MEMALLOC");
233                 ret = DA_ERR_FAIL_TO_MEMALLOC;
234                 goto ERR;
235         }
236         strncpy(wanted_str, wanted_str_start, wanted_str_len);
237
238         b_ret = is_supporting_protocol(wanted_str);
239         if (!b_ret) {
240                 ret = DA_ERR_UNSUPPORTED_PROTOCAL;
241                 goto ERR;
242         }
243
244 ERR:
245         if (wanted_str) {
246                 free(wanted_str);
247                 wanted_str = NULL;
248         }
249
250         if (err_code)
251                 *err_code = ret;
252
253         return b_ret;
254 }
255
256 da_result_t move_file(const char *from_path, const char *to_path)
257 {
258         da_result_t ret = DA_RESULT_OK;
259
260         if (!from_path || !to_path)
261                 return DA_ERR_INVALID_ARGUMENT;
262
263         if (rename(from_path, to_path) != 0) {
264                 DA_LOG_CRITICAL(FileManager,"rename failed : syserr[%d]",errno);
265                 if (errno == EXDEV) {
266                         DA_LOG_CRITICAL(FileManager,"File system is diffrent. Try to copy a file");
267                         ret = copy_file(from_path, to_path);
268                         if (ret == DA_RESULT_OK) {
269                                 remove_file(from_path);
270                         } else {
271                                 if (is_file_exist(to_path))
272                                         remove_file(to_path);
273                                 ret = DA_ERR_FAIL_TO_INSTALL_FILE;
274                         }
275                 } else {
276                         ret = DA_ERR_FAIL_TO_INSTALL_FILE;
277                 }
278         }
279         return ret;
280 }
281
282 void remove_file(const char *file_path)
283 {
284         DA_LOG_FUNC_START(FileManager);
285
286         if (file_path && is_file_exist(file_path)) {
287                 DA_LOG(FileManager,"remove file [%s]", file_path);
288                 if (unlink(file_path) < 0) {
289                         DA_LOG_ERR(FileManager,"file removing failed.");
290                 }
291         }
292 }