a048c2325dfa72077c4c256273b03c1dfd7a6bab
[platform/framework/web/download-provider.git] / src / agent / download-agent-file.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 <dirent.h>
18 #include <unistd.h>
19 #include <math.h>
20
21 #include "download-agent-client-mgr.h"
22 #include "download-agent-debug.h"
23 #include "download-agent-utils.h"
24 #include "download-agent-dl-mgr.h"
25 #include "download-agent-file.h"
26 #include "download-agent-mime-util.h"
27 #include "download-agent-http-mgr.h"
28 #include "download-agent-plugin-conf.h"
29
30 #ifdef _ENABLE_OMA_DRM
31 #include "download-agent-plugin-drm.h"
32 #endif
33
34
35 #define NO_NAME_TEMP_STR "No name"
36
37 static da_result_t  __set_file_size(stage_info *stage);
38 static da_result_t  __saved_file_open(stage_info *stage);
39
40 static char *__derive_extension(stage_info *stage);
41 static da_result_t __divide_file_name_into_pure_name_N_extesion(
42                 const char *in_file_name,
43                 char **out_pure_file_name,
44                 char **out_extension);
45 static da_result_t __get_candidate_file_name(stage_info *stage,
46                 char **out_pure_file_name, char **out_extension);
47
48 static da_result_t __file_write_buf_make_buf(file_info *file_storage);
49 static da_result_t __file_write_buf_destroy_buf(file_info *file_storage);
50 static da_result_t __file_write_buf_flush_buf(stage_info *stage,
51                 file_info *file_storage);
52 static da_result_t __file_write_buf_copy_to_buf(file_info *file_storage,
53                 char *body, int body_len);
54 static da_result_t __file_write_buf_directly_write(stage_info *stage,
55                 file_info *file_storage, char *body, int body_len);
56
57
58 da_result_t create_saved_dir(void)
59 {
60         da_result_t ret = DA_RESULT_OK;
61         char *tmp_default_path = DA_NULL;
62
63         DA_LOG_FUNC_START(FileManager);
64
65         ret = get_default_install_dir(&tmp_default_path);
66         if (ret != DA_RESULT_OK)
67                 goto ERR;
68
69         if (!is_dir_exist(tmp_default_path)) {
70                 ret = create_dir(tmp_default_path);
71         }
72
73 ERR:
74         if (tmp_default_path) {
75                 free(tmp_default_path);
76                 tmp_default_path = DA_NULL;
77         }
78         return ret;
79 }
80
81 da_result_t clean_files_from_dir(char *dir_path)
82 {
83         da_result_t ret = DA_RESULT_OK;
84         struct dirent *d = DA_NULL;
85         DIR *dir;
86         char file_path[DA_MAX_FULL_PATH_LEN] = { 0, };
87
88         DA_LOG_FUNC_START(FileManager);
89
90         if (dir_path == DA_NULL)
91                 return DA_ERR_INVALID_ARGUMENT;
92
93         if (is_dir_exist(dir_path)) {
94                 dir = opendir(dir_path);
95                 if (DA_NULL == dir) {
96                         DA_LOG_ERR(FileManager, "opendir() for %s is failed.", dir_path);
97                         ret = DA_ERR_INVALID_INSTALL_PATH;
98                 } else {
99                         while (DA_NULL != (d = readdir(dir))) {
100                                 DA_LOG(FileManager, "%s",d->d_name);
101                                 if (0 == strncmp(d->d_name, ".", strlen("."))
102                                                 || 0 == strncmp(d->d_name,
103                                                                 "..",
104                                                                 strlen(".."))) {
105                                         continue;
106                                 }
107
108                                 memset(file_path, 0x00, DA_MAX_FULL_PATH_LEN);
109                                 snprintf(file_path, DA_MAX_FULL_PATH_LEN,
110                                                 "%s/%s", dir_path, d->d_name);
111                                 if (remove(file_path) < 0) {
112                                         DA_LOG_ERR(FileManager, "fail to remove file");
113                                 }
114                         }
115
116                         closedir(dir);
117                         if (remove(dir_path) < 0) {
118                                 DA_LOG_ERR(FileManager, "fail to remove dir");
119                         }
120                 }
121         }
122         return ret;
123 }
124
125 /* Priority to obtain MIME Type
126  * 1. HTTP response header's <Content-Type> field
127  * 2. from OMA descriptor file's <content-type> attribute (mandatory field)
128  * 3. Otherwise, leave blank for MIME Type
129  */
130 da_result_t get_mime_type(stage_info *stage, char **out_mime_type)
131 {
132         char *mime_type = DA_NULL;
133
134         if (!GET_STAGE_SOURCE_INFO(stage))
135                 return DA_ERR_INVALID_ARGUMENT;
136
137         /* Priority 1 */
138         if (GET_REQUEST_HTTP_HDR_CONT_TYPE(GET_STAGE_TRANSACTION_INFO(stage))) {
139                 mime_type = GET_REQUEST_HTTP_HDR_CONT_TYPE(GET_STAGE_TRANSACTION_INFO(stage));
140                  DA_LOG(FileManager, "content type from HTTP response header [%s]", mime_type);
141         }
142
143         if (!mime_type) {
144                 DA_LOG(FileManager, "no content type derived");
145                 return DA_RESULT_OK;
146         }
147
148         /* FIXME really need memory allocation? */
149         *out_mime_type = (char *) calloc(1, strlen(mime_type) + 1);
150         if (*out_mime_type) {
151                 snprintf(*out_mime_type, strlen(mime_type) + 1, mime_type);
152                 DA_LOG_VERBOSE(FileManager, "out_mime_type str[%s] ptr[%p] len[%d]",
153                                 *out_mime_type,*out_mime_type,strlen(*out_mime_type));
154         } else {
155                 DA_LOG_ERR(FileManager, "fail to allocate memory");
156                 return DA_ERR_FAIL_TO_MEMALLOC;
157         }
158
159         DA_LOG(FileManager, "mime type = %s", *out_mime_type);
160         return DA_RESULT_OK;
161 }
162
163 da_bool_t is_file_exist(const char *file_path)
164 {
165         struct stat dir_state;
166         int stat_ret;
167
168         if (file_path == DA_NULL) {
169                 DA_LOG_ERR(FileManager, "file path is DA_NULL");
170                 return DA_FALSE;
171         }
172
173         stat_ret = stat(file_path, &dir_state);
174
175         if (stat_ret == 0) {
176                 if (dir_state.st_mode & S_IFREG) {
177                         DA_LOG(FileManager, "Exist! %s is a regular file & its size = %lu", file_path, dir_state.st_size);
178                         return DA_TRUE;
179                 }
180
181                 return DA_FALSE;
182         }
183         return DA_FALSE;
184
185 }
186
187 da_bool_t is_dir_exist(char *file_path)
188 {
189         struct stat dir_state;
190         int stat_ret;
191
192         if (file_path == DA_NULL) {
193                 DA_LOG_ERR(FileManager, "file path is DA_NULL");
194                 return DA_FALSE;
195         }
196
197         stat_ret = stat(file_path, &dir_state);
198
199         if (stat_ret == 0) {
200                 if (dir_state.st_mode & S_IFDIR) {
201                         DA_LOG(FileManager, "Exist! %s is a directory.", file_path);
202                         return DA_TRUE;
203                 }
204
205                 return DA_FALSE;
206         }
207         return DA_FALSE;
208 }
209
210 void get_file_size(char *file_path, unsigned long long *out_file_size)
211 {
212         struct stat dir_state;
213         int stat_ret;
214
215         *out_file_size = -1;
216
217         if (file_path == DA_NULL) {
218                 DA_LOG_ERR(FileManager, "file path is DA_NULL");
219                 return;
220         }
221
222         /* Please do not use ftell() to obtain file size, use stat instead.
223          *  This is a guide from www.securecoding.cert.org
224          *    : FIO19-C. Do not use fseek() and ftell() to compute the size of a file
225          */
226         stat_ret = stat(file_path, &dir_state);
227         if (stat_ret == 0) {
228                 if (dir_state.st_mode & S_IFREG) {
229                         DA_LOG(FileManager, "size = %lu", dir_state.st_size);
230                         *out_file_size = dir_state.st_size;
231                 }
232         }
233         return;
234 }
235
236 da_result_t __saved_file_open(stage_info *stage)
237 {
238         da_result_t ret = DA_RESULT_OK;
239         file_info *file_storage = DA_NULL;
240         char *actual_file_path = DA_NULL;
241         void *fd = DA_NULL;
242
243         DA_LOG_FUNC_START(FileManager);
244
245         file_storage = GET_STAGE_CONTENT_STORE_INFO(stage);
246         if (!file_storage)
247                 return DA_ERR_INVALID_ARGUMENT;
248
249         actual_file_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage);
250         DA_LOG(FileManager, "actual_file_path = %s", actual_file_path);
251         if (!actual_file_path)
252                 return DA_ERR_INVALID_ARGUMENT;
253
254
255         fd = fopen(actual_file_path, "a+"); // for resume
256         if (fd == DA_NULL) {
257                 DA_LOG_ERR(FileManager, "File open failed");
258                 ret = DA_ERR_FAIL_TO_ACCESS_FILE;
259                 goto ERR;
260         }
261         GET_CONTENT_STORE_FILE_HANDLE(file_storage) = fd;
262
263         DA_LOG(FileManager, "file path for saving = %s",
264                         GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage));
265
266 ERR:
267         if (DA_RESULT_OK != ret) {
268                 GET_CONTENT_STORE_FILE_HANDLE(file_storage) = DA_NULL;
269         }
270         return ret;
271 }
272
273 da_result_t __set_file_size(stage_info *stage)
274 {
275         da_result_t ret = DA_RESULT_OK;
276         req_dl_info *stage_req_info = DA_NULL;
277         file_info *file_storage = DA_NULL;
278
279         DA_LOG_FUNC_START(FileManager);
280
281         if (!stage) {
282                 ret = DA_ERR_INVALID_ARGUMENT;
283                 goto ERR;
284         }
285
286         stage_req_info = GET_STAGE_TRANSACTION_INFO(stage);
287
288         file_storage = GET_STAGE_CONTENT_STORE_INFO(stage);
289         if (!file_storage)
290                 goto ERR;
291
292         if (GET_REQUEST_HTTP_HDR_CONT_LEN(stage_req_info) != DA_NULL) {
293                 GET_CONTENT_STORE_FILE_SIZE(file_storage)
294                                 = GET_REQUEST_HTTP_HDR_CONT_LEN(stage_req_info);
295         } else {
296                 GET_CONTENT_STORE_FILE_SIZE(file_storage) = 0;
297         }
298         DA_LOG(FileManager, "file size = %d", GET_CONTENT_STORE_FILE_SIZE(file_storage));
299 ERR:
300         return ret;
301
302 }
303
304 /* Priority to derive extension
305  * 1. according to MIME-Type
306  * 2. if MIME-Type is ambiguous or blank,
307  *    2-1. derived from <Content-Disposition> field's "filename" attribute
308  *    2-2. derived from url
309  * 3. if url does not have extension, leave blank for extension
310  */
311 char *__derive_extension(stage_info *stage)
312 {
313         if (!stage)
314                 return DA_NULL;
315
316         source_info_t *source_info = GET_STAGE_SOURCE_INFO(stage);
317         req_dl_info *request_info = GET_STAGE_TRANSACTION_INFO(stage);
318         file_info *file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage);
319         char *extension = DA_NULL;
320         char *url = DA_NULL;
321
322         /* Priority 1 */
323         char *mime_type = DA_NULL;
324         mime_type = GET_CONTENT_STORE_CONTENT_TYPE(file_info_data);
325         if (mime_type && !is_ambiguous_MIME_Type(mime_type)) {
326                 char *extension = DA_NULL;
327                 da_result_t ret = get_extension_from_mime_type(mime_type, &extension);
328                 if (ret == DA_RESULT_OK && extension)
329                         return extension;
330         }
331
332         /* Priority 2-1 */
333         http_msg_response_t *http_msg_response = DA_NULL;
334         http_msg_response = request_info->http_info.http_msg_response;
335         if (http_msg_response) {
336                 char *file_name = DA_NULL;
337                 da_bool_t b_ret = http_msg_response_get_content_disposition(http_msg_response,
338                                 DA_NULL, &file_name);
339                 if (b_ret && file_name) {
340                         char *extension = DA_NULL;
341                         DA_LOG(FileManager, "Name from Content-Disposition :[%s]", file_name);
342                         __divide_file_name_into_pure_name_N_extesion(file_name, DA_NULL, &extension);
343                                 if (file_name) {
344                                 free(file_name);
345                                 file_name = DA_NULL;
346                         }
347                         if (extension)
348                                 return extension;
349                 }
350         }
351         /* Priority 2-2 */
352         /* If there is location url from response header in case of redirection,
353          * it try to parse the extention name from the location url */
354         if (GET_REQUEST_HTTP_REQ_LOCATION(request_info))
355                 url = GET_REQUEST_HTTP_REQ_LOCATION(request_info);
356         else
357                 url = GET_SOURCE_BASIC_URL(source_info);
358         if (url) {
359                 DA_LOG(FileManager, "url:[%s]", url);
360                 da_bool_t b_ret = da_get_extension_name_from_url(url, &extension);
361                 if (b_ret && extension)
362                         return extension;
363         }
364
365         return DA_NULL;
366 }
367
368 /** Priority for deciding file name
369  * 1. what client wants, which is conveyed by DA_FEATURE_FILE_NAME
370  * 2. 'filename' option on HTTP response header's Content-Disposition field
371  * 3. requesting URL
372  * 4. Otherwise, define it as "No name"
373  */
374 da_result_t __get_candidate_file_name(stage_info *stage, char **out_pure_file_name, char **out_extension)
375 {
376         da_result_t ret = DA_RESULT_OK;
377         source_info_t *source_info = DA_NULL;
378         char *pure_file_name = DA_NULL;
379         char *extension = DA_NULL;
380
381         DA_LOG_FUNC_START(FileManager);
382
383         if (!stage || !out_pure_file_name)
384                 return DA_ERR_INVALID_ARGUMENT;
385
386         source_info = GET_STAGE_SOURCE_INFO(stage);
387         if (!source_info)
388                 return DA_ERR_INVALID_ARGUMENT;
389
390         /* Priority 1 */
391         if (!pure_file_name && GET_DL_USER_FILE_NAME(GET_STAGE_DL_ID(stage))) {
392                 __divide_file_name_into_pure_name_N_extesion(
393                         GET_DL_USER_FILE_NAME(GET_STAGE_DL_ID(stage)),
394                         &pure_file_name, &extension);
395         }
396
397         /* Priority 2 */
398         if (!pure_file_name) {
399                 req_dl_info *request_info = GET_STAGE_TRANSACTION_INFO(stage);
400                 http_msg_response_t *http_msg_response = DA_NULL;
401                 http_msg_response = request_info->http_info.http_msg_response;
402                 if (http_msg_response) {
403                         char *file_name = DA_NULL;
404                         da_bool_t b_ret = http_msg_response_get_content_disposition(http_msg_response,
405                                         DA_NULL, &file_name);
406                         if (b_ret && file_name) {
407                                 DA_LOG(FileManager, "Name from Content-Disposition :[%s]", file_name);
408                                 __divide_file_name_into_pure_name_N_extesion(file_name, &pure_file_name, DA_NULL);
409                                 if (file_name) {
410                                         free(file_name);
411                                         file_name = DA_NULL;
412                                 }
413                         }
414                 }
415         }
416
417         /* Priority 3 */
418         if (!pure_file_name) {
419                 char *url = DA_NULL;
420                 req_dl_info *request_info = GET_STAGE_TRANSACTION_INFO(stage);
421                 /* If there is location url from response header in case of redirection,
422                  * it try to parse the file name from the location url */
423                 if (GET_REQUEST_HTTP_REQ_LOCATION(request_info))
424                         url = GET_REQUEST_HTTP_REQ_LOCATION(request_info);
425                 else
426                         url = GET_SOURCE_BASIC_URL(source_info);
427                 if (url) {
428                         DA_LOG(FileManager, "url: [%s]", url);
429                         da_get_file_name_from_url(url, &pure_file_name);
430                 }
431         }
432
433         /* Priority 4 */
434         if (!pure_file_name) {
435                 pure_file_name = strdup(NO_NAME_TEMP_STR);
436                 if (!pure_file_name) {
437                         ret = DA_ERR_FAIL_TO_MEMALLOC;
438                         goto ERR;
439                 }
440         }
441
442         *out_pure_file_name = pure_file_name;
443         pure_file_name = DA_NULL;
444         DA_LOG(FileManager, "candidate file name [%s]", *out_pure_file_name);
445
446         if (out_extension) {
447                 if (extension) {
448                         *out_extension = extension;
449                         extension = DA_NULL;
450                 } else {
451                         *out_extension = __derive_extension(stage);
452                         DA_LOG(FileManager, "candidate extension [%s]", *out_extension);
453                 }
454         }
455
456         if (extension)
457                 free(extension);
458
459         return DA_RESULT_OK;
460
461 ERR:
462         if (extension)
463                 free(extension);
464
465         return ret;
466 }
467
468 da_result_t __decide_file_path(stage_info *stage)
469 {
470         da_result_t ret = DA_RESULT_OK;
471         char *temp_dir = DA_NULL;
472         char *extension = DA_NULL;
473         char *file_name_without_extension = DA_NULL;
474         char *tmp_file_path = DA_NULL;
475         char *user_install_path = DA_NULL;
476         file_info *file_info_data = DA_NULL;
477         int len = 0;
478         DA_LOG_FUNC_START(FileManager);
479
480         file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage);
481         if (!file_info_data)
482                 return DA_ERR_INVALID_ARGUMENT;
483
484
485         /* If the installed path which user want is set, the temporary directory is same to the installation directory.
486          * Otherwise, the default temporary directory is used.
487          */
488         user_install_path = GET_DL_USER_INSTALL_PATH(GET_STAGE_DL_ID(stage));
489         if (user_install_path) {
490                 len = strlen(user_install_path);
491                 temp_dir = (char *)calloc(len + 1, sizeof(char));
492                 if (!temp_dir) {
493                         ret = DA_ERR_FAIL_TO_MEMALLOC;
494                         goto ERR;
495                 }
496                 memcpy(temp_dir, user_install_path, len);
497                 temp_dir[len] = '\0';
498
499         } else {
500                 ret = get_default_install_dir(&temp_dir);
501                 if (DA_RESULT_OK != ret || DA_NULL == temp_dir) {
502                         goto ERR;
503                 }
504         }
505
506         ret = __get_candidate_file_name(stage, &file_name_without_extension, &extension);
507         if (ret != DA_RESULT_OK)
508                 goto ERR;
509
510         // for resume
511         tmp_file_path = get_full_path_avoided_duplication(temp_dir, file_name_without_extension, extension);
512         if (tmp_file_path) {
513                 GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage))
514                                 = tmp_file_path;
515                 tmp_file_path = DA_NULL;
516         } else {
517                 ret = DA_ERR_FAIL_TO_ACCESS_FILE;
518                 goto ERR;
519         }
520
521         if (file_name_without_extension && !GET_CONTENT_STORE_PURE_FILE_NAME(file_info_data)) {
522                 GET_CONTENT_STORE_PURE_FILE_NAME(file_info_data) = file_name_without_extension;
523                 file_name_without_extension = DA_NULL;
524         }
525
526         if (extension && !GET_CONTENT_STORE_EXTENSION(file_info_data)) {
527                 GET_CONTENT_STORE_EXTENSION(file_info_data) = extension;
528                 extension = DA_NULL;
529         }
530
531 ERR:
532         DA_LOG(FileManager, "decided file path = %s", GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_info_data));
533         if (temp_dir) {
534                 free(temp_dir);
535                 temp_dir = DA_NULL;
536         }
537         if (file_name_without_extension) {
538                 free(file_name_without_extension);
539                 file_name_without_extension = DA_NULL;
540         }
541         if (extension) {
542                 free(extension);
543                 extension = DA_NULL;
544         }
545         return ret;
546 }
547
548 char *get_full_path_avoided_duplication(char *in_dir, char *in_candidate_file_name, char *in_extension)
549 {
550         char *dir = in_dir;
551         char *file_name = in_candidate_file_name;
552         char *extension = in_extension;
553         char *final_path = DA_NULL;
554
555         int final_path_len = 0;
556         int extension_len = 0;
557
558         int suffix_count = 0;   /* means suffix on file name. up to "_99" */
559         const int max_suffix_count = 99;
560         int suffix_len = (int)log10(max_suffix_count+1) + 1;    /* 1 means "_" */
561
562         if (!in_dir || !in_candidate_file_name)
563                 return DA_NULL;
564
565 //      DA_LOG_FUNC_START(FileManager);
566         DA_LOG(FileManager, "in_candidate_file_name=[%s], in_extension=[%s]", in_candidate_file_name, in_extension);
567
568         if (extension)
569                 extension_len = strlen(extension);
570
571         /* first 1 for "/", second 1 for ".", last 1 for DA_NULL */
572         final_path_len = strlen(dir) + 1 + strlen(file_name) + 1
573                         + suffix_len + extension_len + 1;
574
575         final_path = (char*)calloc(1, final_path_len);
576         if (!final_path) {
577                 DA_LOG_ERR(FileManager, "DA_ERR_FAIL_TO_MEMALLOC");
578                 return DA_NULL;
579         }
580
581         do {
582                 /* e.g) /tmp/abc.jpg
583                  * if there is no extension name, just make a file name without extension */
584                 if (0 == extension_len) {
585                         if (suffix_count == 0) {
586                                 snprintf(final_path, final_path_len,
587                                                 "%s/%s", dir, file_name);
588                         } else {
589                                 snprintf(final_path, final_path_len,
590                                                 "%s/%s_%d", dir, file_name, suffix_count);
591                         }
592                 } else {
593                         if (suffix_count == 0) {
594                                 snprintf(final_path, final_path_len,
595                                                 "%s/%s.%s", dir, file_name, extension);
596                         } else {
597                                 snprintf(final_path, final_path_len,
598                                                 "%s/%s_%d.%s",
599                                                 dir, file_name, suffix_count, extension);
600                         }
601                 }
602
603                 if (is_file_exist(final_path)) {
604                         suffix_count++;
605                         if (suffix_count > max_suffix_count) {
606                                 free(final_path);
607                                 final_path = DA_NULL;
608                                 break;
609                         } else {
610                                 memset(final_path, 0x00, final_path_len);
611                                 continue;
612                         }
613                 }
614
615                 break;
616         } while (1);
617
618         DA_LOG(FileManager, "decided path = [%s]", final_path);
619         return final_path;
620 }
621
622 da_result_t __divide_file_name_into_pure_name_N_extesion(const char *in_file_name, char **out_pure_file_name, char **out_extension)
623 {
624         char *file_name = DA_NULL;
625         char *tmp_ptr = DA_NULL;
626         char temp_file[DA_MAX_FILE_PATH_LEN] = {0,};
627         char tmp_ext[DA_MAX_STR_LEN] = {0,};
628         int len = 0;
629         da_result_t ret = DA_RESULT_OK;
630
631         DA_LOG_FUNC_START(FileManager);
632
633         if (!in_file_name)
634                 return DA_ERR_INVALID_ARGUMENT;
635
636         file_name = (char *)in_file_name;
637         tmp_ptr = strrchr(file_name, '.');
638         if (tmp_ptr)
639                 tmp_ptr++;
640         if (tmp_ptr && out_extension) {
641                 strncpy((char*) tmp_ext, tmp_ptr, sizeof(tmp_ext) - 1);
642                 *out_extension = strdup((const char*) tmp_ext);
643                 DA_LOG(FileManager, "extension [%s]", *out_extension);
644         }
645
646         if (!out_pure_file_name)
647                 return ret;
648
649         if (tmp_ptr)
650                 len = tmp_ptr - file_name - 1;
651         else
652                 len = strlen(file_name);
653
654         if (len >= DA_MAX_FILE_PATH_LEN) {
655                 strncpy((char*) temp_file, file_name,
656                                 DA_MAX_FILE_PATH_LEN - 1);
657         } else {
658                 strncpy((char*) temp_file, file_name, len);
659         }
660
661         delete_prohibited_char((char*) temp_file,
662                         strlen((char*) temp_file));
663         if (strlen(temp_file) < 1) {
664                 *out_pure_file_name = strdup(NO_NAME_TEMP_STR);
665         } else {
666                 *out_pure_file_name = strdup(
667                                 (const char*) temp_file);
668         }
669
670         DA_LOG(FileManager, "pure file name [%s]", *out_pure_file_name);
671         return ret;
672 }
673
674 da_result_t __file_write_buf_make_buf(file_info *file_storage)
675 {
676         da_result_t ret = DA_RESULT_OK;
677         char *buffer = DA_NULL;
678
679         DA_LOG_FUNC_START(FileManager);
680
681         buffer = (char*) calloc(DOWNLOAD_NOTIFY_LIMIT, 1);
682         if (DA_NULL == buffer) {
683                 DA_LOG_ERR(FileManager, "Calloc failure ");
684                 ret = DA_ERR_FAIL_TO_MEMALLOC;
685         } else {
686                 GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0;
687                 GET_CONTENT_STORE_FILE_BUFFER(file_storage) = buffer;
688         }
689
690         return ret;
691 }
692
693 da_result_t __file_write_buf_destroy_buf(file_info *file_storage)
694 {
695         da_result_t ret = DA_RESULT_OK;
696
697         DA_LOG_FUNC_START(FileManager);
698
699         if (GET_CONTENT_STORE_FILE_BUFFER(file_storage))
700                 free(GET_CONTENT_STORE_FILE_BUFFER(file_storage));
701
702         GET_CONTENT_STORE_FILE_BUFFER(file_storage) = DA_NULL;
703         GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0;
704
705         return ret;
706 }
707
708 da_result_t __file_write_buf_flush_buf(stage_info *stage, file_info *file_storage)
709 {
710         da_result_t ret = DA_RESULT_OK;
711         char *buffer = DA_NULL;
712         int buffer_size = 0;
713         int write_success_len = 0;
714         void *fd = DA_NULL;
715
716         //      DA_LOG_FUNC_START(FileManager);
717
718         buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage);
719         buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage);
720
721         if (buffer_size == 0) {
722                 DA_LOG_ERR(FileManager, "no data on buffer..");
723                 return ret;
724         }
725
726         fd = GET_CONTENT_STORE_FILE_HANDLE(file_storage);
727         if (DA_NULL == fd) {
728                 DA_LOG_ERR(FileManager, "There is no file handle.");
729
730                 ret = DA_ERR_FAIL_TO_ACCESS_FILE;
731                 goto ERR;
732         }
733
734         write_success_len = fwrite(buffer, sizeof(char), buffer_size,
735                         (FILE *) fd);
736         /* FIXME : This can be necessary later due to progressive download.
737          * The solution for reducing fflush is needed */
738         //fflush((FILE *) fd);
739         if (write_success_len != buffer_size) {
740                 DA_LOG_ERR(FileManager, "write  fails ");
741                 ret = DA_ERR_FAIL_TO_ACCESS_FILE;
742                 goto ERR;
743         }
744         GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
745                         += write_success_len;
746         DA_LOG(FileManager, "write %d bytes", write_success_len);
747
748         IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(file_storage) = DA_TRUE;
749         GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0;
750
751 ERR:
752         return ret;
753 }
754
755 da_result_t __file_write_buf_copy_to_buf(file_info *file_storage, char *body,
756                 int body_len)
757 {
758         da_result_t ret = DA_RESULT_OK;
759         char *buffer = DA_NULL;
760         int buffer_size = 0;
761
762         //      DA_LOG_FUNC_START(FileManager);
763
764         buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage);
765         buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage);
766
767         memcpy(buffer + buffer_size, body, body_len);
768         GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) += body_len;
769
770         return ret;
771 }
772
773 da_result_t __file_write_buf_directly_write(stage_info *stage,
774                 file_info *file_storage, char *body, int body_len)
775 {
776         da_result_t ret = DA_RESULT_OK;
777         int write_success_len = 0;
778         void *fd = DA_NULL;
779
780         //      DA_LOG_FUNC_START(FileManager);
781
782         fd = GET_CONTENT_STORE_FILE_HANDLE(file_storage);
783         if (DA_NULL == fd) {
784                 DA_LOG_ERR(FileManager, "There is no file handle.");
785
786                 ret = DA_ERR_FAIL_TO_ACCESS_FILE;
787                 goto ERR;
788         }
789
790         write_success_len = fwrite(body, sizeof(char), body_len,
791                         (FILE *) fd);
792         /* FIXME : This can be necessary later due to progressive download.
793          * The solution for reducing fflush is needed */
794         //fflush((FILE *) fd);
795         if (write_success_len != body_len) {
796                 DA_LOG_ERR(FileManager, "write  fails ");
797                 ret = DA_ERR_FAIL_TO_ACCESS_FILE;
798                 goto ERR;
799         }
800         GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
801                         += write_success_len;
802         DA_LOG(FileManager, "write %d bytes", write_success_len);
803         IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(file_storage) = DA_TRUE;
804
805 ERR:
806         return ret;
807 }
808
809 da_result_t file_write_ongoing(stage_info *stage, char *body, int body_len)
810 {
811         da_result_t ret = DA_RESULT_OK;
812         file_info *file_storage = DA_NULL;
813         int buffer_size = 0;
814         char *buffer = DA_NULL;
815
816         //      DA_LOG_FUNC_START(FileManager);
817
818         file_storage = GET_STAGE_CONTENT_STORE_INFO(stage);
819         if (!file_storage) {
820                 DA_LOG_ERR(FileManager, "file_info is empty.");
821                 ret = DA_ERR_FAIL_TO_ACCESS_FILE;
822                 goto ERR;
823         }
824
825         buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage);
826         buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage);
827         IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(file_storage) = DA_FALSE;
828
829         if (DA_NULL == buffer) {
830                 if (body_len < DOWNLOAD_NOTIFY_LIMIT) {
831                         ret = __file_write_buf_make_buf(file_storage);
832                         if (ret != DA_RESULT_OK)
833                                 goto ERR;
834
835                         __file_write_buf_copy_to_buf(file_storage, body, body_len);
836                 } else {
837                         ret = __file_write_buf_directly_write(stage,
838                                         file_storage, body, body_len);
839                         if (ret != DA_RESULT_OK)
840                                 goto ERR;
841                 }
842         } else {
843                 if (DOWNLOAD_NOTIFY_LIMIT <= body_len) {
844                         ret = __file_write_buf_flush_buf(stage, file_storage);
845                         if (ret != DA_RESULT_OK)
846                                 goto ERR;
847
848                         ret = __file_write_buf_directly_write(stage,
849                                         file_storage, body, body_len);
850                         if (ret != DA_RESULT_OK)
851                                 goto ERR;
852
853                 } else if ((DOWNLOAD_NOTIFY_LIMIT - buffer_size) <= body_len) {
854                         ret = __file_write_buf_flush_buf(stage, file_storage);
855                         if (ret != DA_RESULT_OK)
856                                 goto ERR;
857
858                         __file_write_buf_copy_to_buf(file_storage, body, body_len);
859                 } else {
860                         __file_write_buf_copy_to_buf(file_storage, body, body_len);
861                 }
862         }
863
864 ERR:
865         if (ret != DA_RESULT_OK) {
866                 if (file_storage) {
867                         GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0;
868                         if (GET_CONTENT_STORE_FILE_BUFFER(file_storage)) {
869                                 free(
870                                                 GET_CONTENT_STORE_FILE_BUFFER(file_storage));
871                                 GET_CONTENT_STORE_FILE_BUFFER(file_storage)
872                                                 = DA_NULL;
873                         }
874                 }
875         }
876         return ret;
877 }
878
879 da_result_t file_write_complete(stage_info *stage)
880 {
881         da_result_t ret = DA_RESULT_OK;
882         file_info*file_storage = DA_NULL;
883         char *buffer = DA_NULL;
884         unsigned int buffer_size = 0;
885         void *fd = DA_NULL;
886
887         DA_LOG_FUNC_START(FileManager);
888
889         file_storage = GET_STAGE_CONTENT_STORE_INFO(stage);
890         if (!file_storage) {
891                 DA_LOG_ERR(FileManager, "file_info is DA_NULL.");
892                 ret = DA_ERR_FAIL_TO_ACCESS_FILE;
893                 goto ERR;
894         }
895
896         buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage);
897         buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage);
898
899         if (DA_NULL == buffer) {
900                 DA_LOG_ERR(FileManager, "file buffer is DA_NULL");
901         } else {
902                 if (buffer_size != 0) {
903                         ret = __file_write_buf_flush_buf(stage, file_storage);
904                         if (ret != DA_RESULT_OK)
905                                 goto ERR;
906                 }
907                 __file_write_buf_destroy_buf(file_storage);
908         }
909         fd = GET_CONTENT_STORE_FILE_HANDLE(file_storage);
910
911         if (fd) {
912                 fclose(fd);
913                 fd = DA_NULL;
914         }
915         GET_CONTENT_STORE_FILE_HANDLE(file_storage) = DA_NULL;
916 ERR:
917         return ret;
918 }
919
920 da_result_t start_file_writing(stage_info *stage)
921 {
922         da_result_t ret = DA_RESULT_OK;
923         file_info *file_info_data = DA_NULL;
924
925         DA_LOG_FUNC_START(FileManager);
926
927         file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage);
928         ret = get_mime_type(stage,
929                         &GET_CONTENT_STORE_CONTENT_TYPE(file_info_data));
930         if (ret != DA_RESULT_OK)
931                 goto ERR;
932
933         ret = __decide_file_path(stage);
934         if (ret != DA_RESULT_OK)
935                 goto ERR;
936
937         ret = __set_file_size(stage);
938         if (DA_RESULT_OK != ret)
939                 goto ERR;
940
941         GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
942                         = 0;
943
944         ret = __saved_file_open(stage);
945
946 ERR:
947         return ret;
948 }
949
950
951 da_result_t start_file_writing_append(stage_info *stage)
952 {
953         da_result_t ret = DA_RESULT_OK;
954
955         DA_LOG_FUNC_START(FileManager);
956
957         ret = __saved_file_open(stage);
958
959         return ret;
960 }
961
962 // for resume with new download request
963 da_result_t start_file_writing_append_with_new_download(stage_info *stage)
964 {
965         da_result_t ret = DA_RESULT_OK;
966         file_info *file_storage = DA_NULL;
967         char *original_file_path = DA_NULL;
968         char *temp_file_path = DA_NULL;
969         char *extension = DA_NULL;
970         char *file_name_without_extension = DA_NULL;
971         req_dl_info *request_info = DA_NULL;
972         unsigned long long temp_file_size = 0;
973
974         DA_LOG_FUNC_START(FileManager);
975
976         file_storage = GET_STAGE_CONTENT_STORE_INFO(stage);
977         if (!file_storage)
978                 return DA_ERR_INVALID_ARGUMENT;
979         request_info = GET_STAGE_TRANSACTION_INFO(stage);
980         if (!request_info)
981                 return DA_ERR_INVALID_ARGUMENT;
982         temp_file_path = GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(request_info);
983         if (!temp_file_path)
984                 return DA_ERR_INVALID_ARGUMENT;
985         original_file_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage);
986
987         GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage) = strdup(temp_file_path);
988
989         if (original_file_path)
990                 free(original_file_path);
991
992         ret = get_mime_type(stage,
993                         &GET_CONTENT_STORE_CONTENT_TYPE(file_storage));
994         if (ret != DA_RESULT_OK)
995                 goto ERR;
996
997         ret = __get_candidate_file_name(stage, &file_name_without_extension, &extension);
998         if (ret != DA_RESULT_OK)
999                 goto ERR;
1000
1001         if (file_name_without_extension) {
1002                 if (!GET_CONTENT_STORE_PURE_FILE_NAME(file_storage)) {
1003                         GET_CONTENT_STORE_PURE_FILE_NAME(file_storage) = file_name_without_extension;
1004                         file_name_without_extension = DA_NULL;
1005                 } else {
1006                         free(file_name_without_extension);
1007                         file_name_without_extension = DA_NULL;
1008                 }
1009         }
1010
1011         if (extension) {
1012                 if (!GET_CONTENT_STORE_EXTENSION(file_storage)) {
1013                         GET_CONTENT_STORE_EXTENSION(file_storage) = extension;
1014                         extension = DA_NULL;
1015                 } else {
1016                         free(extension);
1017                         extension = DA_NULL;
1018                 }
1019         }
1020
1021         ret = __set_file_size(stage);
1022         if (DA_RESULT_OK != ret)
1023                 goto ERR;
1024         get_file_size(temp_file_path, &temp_file_size);
1025         if (temp_file_size < 1)
1026                 goto ERR;
1027
1028         GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
1029                         = temp_file_size;
1030
1031         ret = __saved_file_open(stage);
1032         return ret;
1033 ERR:
1034         if (file_name_without_extension) {
1035                 free(file_name_without_extension);
1036                 file_name_without_extension = DA_NULL;
1037         }
1038
1039         if (extension) {
1040                 free(extension);
1041                 extension = DA_NULL;
1042         }
1043         return ret;
1044 }
1045
1046 da_result_t discard_download(stage_info *stage)
1047 {
1048         da_result_t ret = DA_RESULT_OK;
1049         file_info *file_storage = DA_NULL;
1050         FILE *f_handle = DA_NULL;
1051
1052         DA_LOG_FUNC_START(FileManager);
1053
1054         file_storage = GET_STAGE_CONTENT_STORE_INFO(stage);
1055
1056         f_handle = GET_CONTENT_STORE_FILE_HANDLE(file_storage);
1057         if (f_handle) {
1058                 fclose(f_handle);
1059                 GET_CONTENT_STORE_FILE_HANDLE(file_storage) = DA_NULL;
1060         }
1061         return ret;
1062 }
1063
1064 void clean_paused_file(stage_info *stage)
1065 {
1066         file_info *file_info_data = DA_NULL;
1067         char *paused_file_path = DA_NULL;
1068         FILE *fd = DA_NULL;
1069
1070         DA_LOG_FUNC_START(FileManager);
1071
1072         file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage);
1073
1074         fd = GET_CONTENT_STORE_FILE_HANDLE(file_info_data);
1075         if (fd) {
1076                 fclose(fd);
1077                 GET_CONTENT_STORE_FILE_HANDLE(file_info_data) = DA_NULL;
1078         }
1079
1080         paused_file_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_info_data);
1081         remove_file((const char*) paused_file_path);
1082
1083         return;
1084 }
1085
1086 da_result_t replace_content_file_in_stage(stage_info *stage,
1087                 const char *dest_dd_file_path)
1088 {
1089         da_result_t ret = DA_RESULT_OK;
1090         char *dd_file_path = DA_NULL;
1091         int len;
1092
1093         DA_LOG_FUNC_START(FileManager);
1094
1095         if (!dest_dd_file_path
1096                         && (DA_FALSE == is_file_exist(dest_dd_file_path))) {
1097                 ret = DA_ERR_INVALID_ARGUMENT;
1098                 goto ERR;
1099         }
1100
1101         dd_file_path
1102                         =GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage));
1103
1104         if (DA_NULL != dd_file_path) {
1105                 remove_file((const char*) dd_file_path);
1106                 free(dd_file_path);
1107         }
1108         len = strlen(dest_dd_file_path);
1109         dd_file_path = calloc(1, len + 1);
1110         if (!dd_file_path) {
1111                 ret = DA_ERR_FAIL_TO_MEMALLOC;
1112                 goto ERR;
1113         }
1114         strncpy(dd_file_path, dest_dd_file_path, len);
1115         GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage))
1116                         = dd_file_path;
1117
1118 ERR:
1119         return ret;
1120
1121 }
1122
1123 da_result_t copy_file(const char *src, const char *dest)
1124 {
1125         FILE *fs = DA_NULL;
1126         FILE *fd = DA_NULL;
1127         int freadnum = 0;
1128         int fwritenum = 0;
1129         char buff[4096] = { 0, };
1130
1131         DA_LOG_FUNC_START(FileManager);
1132
1133         /* open files to copy */
1134         fs = fopen(src, "rb");
1135         if (!fs) {
1136                 DA_LOG_ERR(FileManager, "Fail to open src file");
1137                 return DA_ERR_FAIL_TO_ACCESS_FILE;
1138         }
1139
1140         fd = fopen(dest, "wb");
1141         if (!fd) {
1142                 DA_LOG_ERR(FileManager, "Fail to open dest file");
1143
1144                 fclose(fs);
1145                 return DA_ERR_FAIL_TO_ACCESS_FILE;
1146         }
1147
1148         /* actual copy */
1149         while (!feof(fs)) {
1150                 memset(buff, 0x00, 4096);
1151                 freadnum = fread(buff, sizeof(char), sizeof(buff), fs);
1152                 if (freadnum > 0) {
1153                         fwritenum = fwrite(buff, sizeof(char), freadnum, fd);
1154                         if (fwritenum <= 0) {
1155                                 DA_LOG(FileManager, "written = %d",fwritenum);
1156                                 break;
1157                         }
1158                 } else {
1159                         DA_LOG(FileManager, "read = %d",freadnum);
1160                         break;
1161                 }
1162         }
1163
1164         fclose(fd);
1165         fclose(fs);
1166
1167         return DA_RESULT_OK;
1168 }
1169
1170 da_result_t create_dir(const char *install_dir)
1171 {
1172         da_result_t ret = DA_RESULT_OK;
1173                 /* read/write/search permissions for owner and group,
1174                  * and with read/search permissions for others. */
1175         if (mkdir(install_dir, S_IRWXU | S_IRWXG | S_IRWXO)) {
1176                 DA_LOG_ERR(FileManager, "Fail to creaate directory [%s]", install_dir);
1177                 ret = DA_ERR_FAIL_TO_ACCESS_STORAGE;
1178         } else {
1179                 DA_LOG(FileManager, "[%s] is created!", install_dir);
1180         }
1181         return ret;
1182 }
1183
1184
1185 da_result_t get_default_dir(char **out_path)
1186 {
1187         char *tmp_default_path = DA_NULL;
1188         int len = 0;
1189
1190         if (!out_path) {
1191                 DA_LOG_ERR(ClientNoti, "DA_ERR_INVALID_ARGUMENT");
1192                 return DA_ERR_INVALID_ARGUMENT;
1193         }
1194
1195         len = strlen(DA_DEFAULT_FILE_DIR_PATH);
1196         tmp_default_path = calloc(len + 1, sizeof(char));
1197         if (!tmp_default_path) {
1198                 return DA_ERR_FAIL_TO_MEMALLOC;
1199         }
1200
1201         memcpy(tmp_default_path, DA_DEFAULT_FILE_DIR_PATH, len);
1202         tmp_default_path[len] = '\0';
1203
1204         *out_path = tmp_default_path;
1205
1206         DA_LOG_VERBOSE(FileManager, "default temp path = [%s]", *out_path);
1207
1208         return DA_RESULT_OK;
1209 }
1210
1211 da_result_t get_default_install_dir(char **out_path)
1212 {
1213         char *default_path = DA_NULL;
1214         da_storage_type_t type;
1215         da_result_t ret = DA_RESULT_OK;
1216         int len = 0;
1217
1218         if (!out_path) {
1219                 DA_LOG_ERR(ClientNoti, "DA_ERR_INVALID_ARGUMENT");
1220                 return DA_ERR_INVALID_ARGUMENT;
1221         }
1222         ret = get_storage_type(&type);
1223         if (DA_RESULT_OK != ret)
1224                 return ret;
1225         if (type == DA_STORAGE_MMC)
1226                 len = strlen(DA_DEFAULT_INSTALL_PATH_FOR_MMC);
1227         else
1228                 len = strlen(DA_DEFAULT_INSTALL_PATH_FOR_PHONE);
1229
1230         default_path = calloc(len + 1, sizeof(char));
1231         if (!default_path) {
1232                 return DA_ERR_FAIL_TO_MEMALLOC;
1233         }
1234         if (type == DA_STORAGE_MMC)
1235                 memcpy(default_path, DA_DEFAULT_INSTALL_PATH_FOR_MMC, len);
1236         else // DA_STROAGE_PHONE
1237                 memcpy(default_path, DA_DEFAULT_INSTALL_PATH_FOR_PHONE, len);
1238         default_path[len] = '\0';
1239
1240         *out_path = default_path;
1241
1242         DA_LOG_VERBOSE(FileManager, "default temp path = [%s]", *out_path);
1243         return DA_RESULT_OK;
1244 }