046b98b4d6287ba5efc7d013d6e2c0af582ef1e3
[platform/core/system/sync-agent.git] / src / framework / fsapi / operation.c
1 /*
2  * sync-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <stdarg.h>
21 #include <string.h>
22 #include <time.h>
23 #include <errno.h>
24 #include <unistd.h>
25 #include <sys/vfs.h>            /* for statfs */
26 #include "fsapi/operation.h"
27 #include "fsapi/operation_internal.h"
28 #include "fsapi/util.h"
29 #include "security-assistant/md5.h"
30
31 #include "utility/sync_util.h"
32
33 #ifndef EXPORT_API
34 #define EXPORT_API __attribute__ ((visibility("default")))
35 #endif
36
37 #ifndef SYNC_AGENT_LOG
38 #undef LOG_TAG
39 #define LOG_TAG "AF_FS"
40 #endif
41
42 #define FS_BUFFER_SIZE 2048
43
44 static bool file_append_started = FALSE;
45 static bool file_read_started = FALSE;
46 static char *temp_filename_kept = NULL;
47 static char *requested_filename_kept = NULL;
48 static FILE *fd_source_kept = NULL;
49
50 static unsigned char _sync_str_to_hex_char(unsigned char hex);
51
52 EXPORT_API sync_agent_fsapi_return_e sync_agent_is_existing_fs(const char *file_name)
53 {
54         _EXTERN_FUNC_ENTER;
55
56         retvm_if(file_name == NULL, 0, "file_name paramter is NULL !!!");
57
58         _EXTERN_FUNC_EXIT;
59
60         return fs_is_existing(file_name);
61 }
62
63 EXPORT_API sync_agent_fsapi_return_e sync_agent_get_fs_info(char **result)
64 {
65         _EXTERN_FUNC_ENTER;
66
67         retvm_if(result == NULL, 0, "result paramter is NULL !!!");
68
69         int ret = 0;
70
71         long double free_size = 0;
72         long double total_size = 0;
73
74         int file_name_len_max = 256;
75         int folder_name_len_max = 256;
76
77         char *file_name_prevenet_char = ":;*?/<>\"";
78         char *folder_name_prevent_char = ":;*?/<>\"";
79
80         int file_name_code_schema = 2;
81         int allow_dup_name = 0;
82         int folder_depth_max = 15;
83
84         ret = sync_agent_get_fs_mem_size("/opt/usr/media", &free_size, &total_size);
85         if (!ret) {
86                 _DEBUG_ERROR("[sync_agent_get_fs_info] getting mem size fail");
87                 return SYNC_AGENT_FSAPI_FALSE;
88         }
89
90         *result = g_strdup_printf("%.0Lf,%d,%s,%d,%d,%d,%d,%s", total_size, file_name_len_max, file_name_prevenet_char, file_name_code_schema, allow_dup_name, folder_depth_max, folder_name_len_max, folder_name_prevent_char);
91
92         _EXTERN_FUNC_EXIT;
93
94         return SYNC_AGENT_FSAPI_TRUE;
95 }
96
97 EXPORT_API sync_agent_fsapi_return_e sync_agent_free_fs_info(char *result)
98 {
99         _EXTERN_FUNC_ENTER;
100
101         retvm_if(result == NULL, 0, "result paramter is NULL !!!");
102
103         if (result != NULL)
104                 g_free(result);
105
106         _EXTERN_FUNC_EXIT;
107
108         return SYNC_AGENT_FSAPI_TRUE;
109 }
110
111 EXPORT_API sync_agent_fsapi_return_e sync_agent_get_fs_mem_size(const char *root, long double *size_free, long double *size_total)
112 {
113         _EXTERN_FUNC_ENTER;
114
115         retvm_if(root == NULL, 0, "root paramter is NULL !!!");
116
117         if (!fs_is_existing(root)) {
118                 _DEBUG_ERROR("[%s] Requested instance '%s' not exist.\n", __func__, root);
119                 return SYNC_AGENT_FSAPI_FALSE;
120         }
121
122         struct statfs fs_info;
123
124         if (statfs(root, &fs_info) != 0) {
125                 _DEBUG_ERROR("[sync_agent_get_fs_mem_size] statfs error.");
126                 return SYNC_AGENT_FSAPI_FALSE;
127         }
128
129         *size_free = ((long double)fs_info.f_bavail * (long double)fs_info.f_bsize);    /* / 1024; */
130         *size_total = ((long double)fs_info.f_blocks * (long double)fs_info.f_bsize);   /* / 1024; */
131
132         _DEBUG_INFO("[sync_agent_get_fs_mem_size] FS info root : %s.", root);
133         _DEBUG_INFO("[sync_agent_get_fs_mem_size] FS info free size : %.0f", *size_free);
134         _DEBUG_INFO("[sync_agent_get_fs_mem_size] FS info total size : %.0f", *size_total);
135
136         _EXTERN_FUNC_EXIT;
137
138         return SYNC_AGENT_FSAPI_TRUE;
139 }
140
141 /*
142  * File operation
143  */
144
145 EXPORT_API sync_agent_fsapi_return_e sync_agent_get_file_size(const char *file_name, unsigned long *size)
146 {
147         _EXTERN_FUNC_ENTER;
148
149         retvm_if(file_name == NULL, 0, "file_name paramter is NULL !!!");
150
151         if (!fs_is_existing(file_name) || fs_is_directory(file_name)) {
152                 _DEBUG_ERROR("[%s] Requested instance '%s' not exist, or not a file.\n", __func__, file_name);
153                 return SYNC_AGENT_FSAPI_FALSE;
154         }
155
156         struct stat buf;
157
158         int ret = stat(file_name, &buf);
159         if (ret == -1) {
160                 _DEBUG_ERROR("[%s] stat error : %s", __func__, strerror(errno));
161                 return SYNC_AGENT_FSAPI_FALSE;
162         }
163
164         *size = (unsigned long)buf.st_size;
165
166         _EXTERN_FUNC_EXIT;
167
168         return SYNC_AGENT_FSAPI_TRUE;
169 }
170
171 int fs_get_file_date(const char *file_name, char **time_string)
172 {
173         _EXTERN_FUNC_ENTER;
174
175         retvm_if(file_name == NULL, 0, "file_name paramter is NULL !!!");
176
177         if (!fs_is_existing(file_name) || fs_is_directory(file_name)) {
178                 _DEBUG_ERROR("[%s] Requested instance '%s' not exist, or not a file.\n", __func__, file_name);
179                 return SYNC_AGENT_FSAPI_FALSE;
180         }
181
182         struct stat buf;
183         char time[FS_MAX_TIME_STRING_BUF] = { 0 };
184
185         int ret = stat(file_name, &buf);
186         if (ret == -1) {
187                 _DEBUG_ERROR("[%s] stat error : %s", __func__, strerror(errno));
188                 return SYNC_AGENT_FSAPI_FALSE;
189         }
190
191         fs_get_time_string(&buf.st_mtime, time);
192         *time_string = g_strdup(time);
193
194         _EXTERN_FUNC_EXIT;
195
196         return SYNC_AGENT_FSAPI_TRUE;
197 }
198
199 EXPORT_API sync_agent_fsapi_return_e sync_agent_copy_file(const char *source, const char *dest)
200 {
201         _EXTERN_FUNC_ENTER;
202
203         retvm_if(source == NULL, 0, "source paramter is NULL !!!");
204         retvm_if(dest == NULL, 0, "dest paramter is NULL !!!");
205
206         if (!fs_is_existing(source) || fs_is_directory(source) || fs_is_existing(dest)) {
207                 _DEBUG_ERROR("[%s] Requested source instance '%s' not exist or not a file, or\n", __func__, source);
208                 _DEBUG_ERROR("[%s] requested dest instance '%s' already exist.\n", __func__, dest);
209                 return SYNC_AGENT_FSAPI_FALSE;
210         }
211
212         FILE *f1 = NULL, *f2 = NULL;
213         int ret = 1;
214         char buf[1024 * 100] = { 0 };
215         unsigned long bytes_read = 0;
216         unsigned long bytes_written = 0;
217
218         f1 = (FILE *) g_fopen(source, "rb");
219         if (f1 == NULL) {
220                 _DEBUG_ERROR("[sync_agent_copy_file] file f1 open error.");
221                 ret = 0;
222                 goto return_part;
223         }
224
225         f2 = (FILE *) g_fopen(dest, "wb");
226         if (f2 == NULL) {
227                 _DEBUG_ERROR("[sync_agent_copy_file] file f2 open error.");
228                 ret = 0;
229                 goto return_part;
230         }
231
232         while ((bytes_read = fread(buf, 1, sizeof(buf), f1)) > 0) {
233                 if (bytes_read > sizeof(buf)) {
234                         _DEBUG_ERROR("[sync_agent_copy_file] read error.");
235                         ret = 0;
236                         goto return_part;
237                 }
238
239                 bytes_written = fwrite(buf, 1, bytes_read, f2);
240                 if (!feof(f1) && bytes_written != bytes_read) {
241                         _DEBUG_ERROR("[sync_agent_copy_file] write error.");
242                         ret = 0;
243                         goto return_part;
244                 }
245         }
246
247         _EXTERN_FUNC_EXIT;
248
249  return_part:
250         if (f1 != NULL)
251                 fclose(f1);
252         if (f2 != NULL)
253                 fclose(f2);
254         return ret;
255
256 /*
257         char *body = NULL;
258         unsigned long size;
259
260         if( !File_Read(source, &body, &size) ) {
261                 fprintf(stderr, "[%s] File_Read() returned error.\n", __func__);
262                 return SYNC_AGENT_FSAPI_FALSE;
263         }
264
265         if( !File_Write(dest, body, size) ) {
266                 fprintf(stderr, "[%s] File_Read() returned error.\n", __func__);
267                 return SYNC_AGENT_FSAPI_FALSE;
268         }
269
270         free(body);
271
272         return SYNC_AGENT_FSAPI_TRUE;
273 */
274 }
275
276 EXPORT_API sync_agent_fsapi_return_e sync_agent_delete_file(const char *file_name)
277 {
278         _EXTERN_FUNC_ENTER;
279
280         retvm_if(file_name == NULL, 0, "file_name paramter is NULL !!!");
281
282         if (!fs_is_existing(file_name) || fs_is_directory(file_name)) {
283                 _DEBUG_ERROR("[%s] Requested instance '%s' not exist, or not a file.\n", __func__, file_name);
284                 return SYNC_AGENT_FSAPI_FALSE;
285         }
286
287         int ret = g_unlink(file_name);
288         if (ret == -1) {
289                 _DEBUG_ERROR("[%s] g_unlink error : %s\n", __func__, strerror(errno));
290                 return SYNC_AGENT_FSAPI_FALSE;
291         }
292
293         _EXTERN_FUNC_EXIT;
294
295         return SYNC_AGENT_FSAPI_TRUE;
296 }
297
298 EXPORT_API sync_agent_fsapi_return_e sync_agent_move_file(const char *source, const char *dest)
299 {
300         _EXTERN_FUNC_ENTER;
301
302         retvm_if(source == NULL, 0, "source paramter is NULL !!!");
303         retvm_if(dest == NULL, 0, "dest paramter is NULL !!!");
304
305         if (!fs_is_existing(source) || fs_is_directory(source) || fs_is_existing(dest)) {
306                 _DEBUG_ERROR("[%s] Requested source instance '%s' not exist or not a file, or\n", __func__, source);
307                 _DEBUG_ERROR("[%s] requested dest instance '%s' already exist.\n", __func__, dest);
308                 return SYNC_AGENT_FSAPI_FALSE;
309         }
310
311         int ret = g_rename(source, dest);
312         if (ret == -1) {
313                 _DEBUG_ERROR("[sync_agent_move_file] g_rename error : %s", strerror(errno));
314                 _DEBUG_ERROR("[sync_agent_move_file] source : %s target : %s", source, dest);
315                 return SYNC_AGENT_FSAPI_FALSE;
316         }
317
318         _EXTERN_FUNC_EXIT;
319
320         return SYNC_AGENT_FSAPI_TRUE;
321 }
322
323 EXPORT_API sync_agent_fsapi_return_e sync_agent_rename_file(const char *source, const char *dest)
324 {
325         _EXTERN_FUNC_ENTER;
326
327         retvm_if(source == NULL, 0, "source paramter is NULL !!!");
328         retvm_if(dest == NULL, 0, "dest paramter is NULL !!!");
329
330         _EXTERN_FUNC_EXIT;
331
332         return sync_agent_move_file(source, dest);
333 }
334
335 EXPORT_API sync_agent_fsapi_return_e sync_agent_get_file_list(const char *folder_name, GSList ** list)
336 {
337         _EXTERN_FUNC_ENTER;
338
339         retvm_if(folder_name == NULL, 0, "folder_name paramter is NULL !!!");
340
341         if (!fs_is_existing(folder_name) || !fs_is_directory(folder_name)) {
342                 _DEBUG_ERROR("[%s] Requested instance '%s' not exist, or not a directory.\n", __func__, folder_name);
343                 return SYNC_AGENT_FSAPI_FALSE;
344         }
345
346         struct stat buf;
347         char *path = NULL;
348         char time[FS_MAX_TIME_STRING_BUF] = { 0 };
349         char *list_item = NULL;
350
351         GError *gerror = NULL;
352         GDir *dir = g_dir_open(folder_name, 0, &gerror);
353         if (dir == NULL) {
354                 _DEBUG_ERROR("[%s] g_dir_open error : %s\n", __func__, gerror->message);
355                 g_error_free(gerror);
356                 return SYNC_AGENT_FSAPI_FALSE;
357         }
358
359         const char *file_name = g_dir_read_name(dir);
360
361         for (; file_name; file_name = g_dir_read_name(dir)) {
362
363                 path = g_strdup_printf("%s/%s", folder_name, file_name);
364
365                 if (!fs_is_directory(path)) {
366                         int ret = stat(path, &buf);
367                         if (ret == -1) {
368                                 _DEBUG_ERROR("[%s] g_stat error : %s\n", __func__, strerror(errno));
369                                 return SYNC_AGENT_FSAPI_FALSE;
370                         }
371
372                         fs_get_time_string(&buf.st_mtime, time);
373                         list_item = g_strdup_printf("%s,%ld,%s", file_name, (long)buf.st_size, time);
374
375                         *list = g_slist_append(*list, list_item);
376                 }
377         }
378
379         free(path);
380         g_dir_close(dir);
381         dir = NULL;
382
383         _EXTERN_FUNC_EXIT;
384
385         return SYNC_AGENT_FSAPI_TRUE;
386 }
387
388 EXPORT_API sync_agent_fsapi_return_e sync_agent_read_file(const char *file_name, char **required_contents, unsigned long required_length, unsigned long *size_return, bool * is_final)
389 {
390         _EXTERN_FUNC_ENTER;
391
392         retvm_if(file_name == NULL, 0, "file_name paramter is NULL !!!");
393
394         if (!fs_is_existing(file_name) || fs_is_directory(file_name)) {
395                 _DEBUG_ERROR("[%s] Requested instance '%s' not exist, or not a file.\n", __func__, file_name);
396                 return SYNC_AGENT_FSAPI_FALSE;
397         }
398
399         int ret = 1;
400
401         if ((fd_source_kept == NULL) && !file_read_started) {
402                 fd_source_kept = (FILE *) g_fopen(file_name, "rb");
403                 if (fd_source_kept == NULL) {
404                         _DEBUG_ERROR("[sync_agent_read_file] temp_filename_kept open error.");
405                         ret = 0;
406                         goto return_part;
407                 }
408                 file_read_started = TRUE;
409         } else if ((fd_source_kept != NULL) && file_read_started) {
410         } else {
411                 _DEBUG_ERROR("[%s] internal condition not matching.\n", __func__);
412                 ret = 0;
413                 goto return_part;
414         }
415
416         *required_contents = (char *)calloc(required_length, sizeof(char));
417         if (*required_contents == NULL) {
418                 _DEBUG_ERROR("[sync_agent_read_file] calloc error. [*required_contents]");
419                 ret = 0;
420                 goto return_part;
421         }
422
423         int bytes_read = 0;
424         bytes_read = fread(*required_contents, 1, required_length, fd_source_kept);
425
426         if ((bytes_read > required_length) || ((!feof(fd_source_kept)) && (bytes_read < required_length))) {
427                 _DEBUG_ERROR("[sync_agent_read_file] read error.");
428                 ret = 0;
429                 goto return_part;
430         }
431
432         *size_return = bytes_read;
433
434         if (feof(fd_source_kept)) {
435                 *is_final = TRUE;
436                 goto return_part;
437         }
438
439         _EXTERN_FUNC_EXIT;
440
441         return ret;
442
443  return_part:
444
445         if (fd_source_kept != NULL) {
446                 fclose(fd_source_kept);
447                 fd_source_kept = NULL;
448         }
449         file_read_started = FALSE;
450
451         return ret;
452
453 /*
454         if( !fs_is_existing(file_name) || fs_is_directory(file_name) ) {
455                 fprintf(stderr, "[%s] Requested instance '%s' not exist, or not a file.\n", __func__, file_name);
456                 return SYNC_AGENT_FSAPI_FALSE;
457         }
458
459         GError *gerror = NULL;
460
461         if( !g_file_get_contents(file_name, contents, (gsize*)length, &gerror) ) {
462                 fprintf(stderr, "[%s] g_file_get_contents error : %s\n", __func__, gerror->message);
463
464                 g_error_free(gerror);
465                 return SYNC_AGENT_FSAPI_FALSE;
466         }
467
468         return SYNC_AGENT_FSAPI_TRUE;
469 */
470 }
471
472 EXPORT_API sync_agent_fsapi_return_e sync_agent_read_whole_file(const char *file_name, char **required_contents, unsigned long *size_return)
473 {
474         _EXTERN_FUNC_ENTER;
475
476         retvm_if(file_name == NULL, 0, "file_name paramter is NULL !!!");
477
478         if (!fs_is_existing(file_name) || fs_is_directory(file_name)) {
479                 _DEBUG_ERROR("[%s] Requested instance '%s' not exist, or not a file.\n", __func__, file_name);
480                 return SYNC_AGENT_FSAPI_FALSE;
481         }
482
483         GError *gerror = NULL;
484
485         if (!g_file_get_contents(file_name, required_contents, (gsize *) size_return, &gerror)) {
486                 _DEBUG_ERROR("[%s] g_file_get_contents error : %s\n", __func__, gerror->message);
487
488                 g_error_free(gerror);
489                 return SYNC_AGENT_FSAPI_FALSE;
490         }
491
492         _EXTERN_FUNC_EXIT;
493
494         return SYNC_AGENT_FSAPI_TRUE;
495 }
496
497 EXPORT_API sync_agent_fsapi_return_e sync_agent_free_file(char **requested_contents)
498 {
499         _EXTERN_FUNC_ENTER;
500
501         retvm_if(requested_contents == NULL, 0, "requested_contents paramter is NULL !!!");
502
503         if (*requested_contents != NULL)
504                 free(*requested_contents);
505
506         _EXTERN_FUNC_EXIT;
507
508         return SYNC_AGENT_FSAPI_TRUE;
509 }
510
511 EXPORT_API sync_agent_fsapi_return_e sync_agent_write_file(const char *file_name, const char *contents, unsigned long length, bool is_final, bool overwrite)
512 {
513         _EXTERN_FUNC_ENTER;
514
515         retvm_if(file_name == NULL, 0, "file_name paramter is NULL !!!");
516         retvm_if(contents == NULL, 0, "contents is NULL !!");
517
518         if (!overwrite) {
519                 if (fs_is_existing(file_name)) {
520                         _DEBUG_ERROR("[%s] Requested instance '%s' already exist.\n", __func__, file_name);
521                         return SYNC_AGENT_FSAPI_FALSE;
522                 }
523         }
524
525         FILE *fd_temp = NULL;
526         GError *gerror = NULL;
527         int ret = 1;
528         unsigned long temp_size = 0;
529
530         if ((temp_filename_kept == NULL) && !file_append_started) {
531                 if (!g_file_open_tmp(NULL, &temp_filename_kept, &gerror)) {
532                         _DEBUG_ERROR("[%s] g_file_open_tmp error : %s\n", __func__, gerror->message);
533
534                         g_error_free(gerror);
535                         ret = 0;
536                         goto return_part;
537                 }
538                 _DEBUG_INFO("[sync_agent_write_file] Temp file name kept new : %s", temp_filename_kept);
539
540                 file_append_started = TRUE;
541                 requested_filename_kept = g_strdup(file_name);
542
543         } else if ((temp_filename_kept != NULL) && file_append_started) {
544                 if (!fs_is_existing(temp_filename_kept)) {
545                         _DEBUG_ERROR("[%s] Temp file '%s' not existing.\n", __func__, temp_filename_kept);
546                         ret = 0;
547                         goto return_part;
548                 }
549                 _DEBUG_INFO("[sync_agent_write_file] Temp file %s kept previously, existing", temp_filename_kept);
550
551         } else {
552                 _DEBUG_ERROR("[%s] internal condition not matching.\n", __func__);
553                 ret = 0;
554                 goto return_part;
555         }
556
557         if (temp_filename_kept != NULL) {
558                 fd_temp = (FILE *) g_fopen(temp_filename_kept, "ab");
559         } else {
560                 goto return_part;
561         }
562
563         if (fd_temp == NULL) {
564                 _DEBUG_ERROR("[sync_agent_write_file] temp file open error.");
565                 ret = 0;
566                 goto return_part;
567         }
568
569         if (fwrite(contents, 1, length, fd_temp) != length) {
570                 _DEBUG_ERROR("[sync_agent_write_file] fwrite error.");
571                 ret = 0;
572                 goto return_part;
573         }
574
575         if (fd_temp != NULL) {
576                 fclose(fd_temp);
577                 fd_temp = NULL;
578         }
579
580         sync_agent_get_file_size(temp_filename_kept, &temp_size);
581         _DEBUG_INFO("[sync_agent_write_file] temp file size %ld", temp_size);
582
583         if (is_final) {
584                 if (overwrite) {
585                         if (fs_is_existing(file_name)) {
586                                 if (!sync_agent_delete_file(file_name)) {
587                                         _DEBUG_ERROR("[sync_agent_write_file] deleting destination file for overwriting fail.");
588                                         ret = 0;
589                                 } else {
590                                         if (!sync_agent_copy_file(temp_filename_kept, file_name)) {
591                                                 _DEBUG_ERROR("[sync_agent_write_file] copying temp file to destination fail.");
592                                                 ret = 0;
593                                         } else {
594                                                 if (!sync_agent_delete_file(temp_filename_kept)) {
595                                                         _DEBUG_ERROR("[sync_agent_write_file] deleting temp file fail.");
596                                                         ret = 0;
597                                                 }
598                                         }
599                                 }
600                         } else {
601                                 if (!sync_agent_copy_file(temp_filename_kept, file_name)) {
602                                         _DEBUG_ERROR("[sync_agent_write_file] copying temp file to destination fail.");
603                                         ret = 0;
604                                 } else {
605                                         if (!sync_agent_delete_file(temp_filename_kept)) {
606                                                 _DEBUG_ERROR("[sync_agent_write_file] deleting temp file fail.");
607                                                 ret = 0;
608                                         }
609                                 }
610                         }
611                 } else {
612                         if (!sync_agent_copy_file(temp_filename_kept, file_name)) {
613                                 _DEBUG_ERROR("[sync_agent_write_file] copying temp file to destination fail.");
614                                 ret = 0;
615                         } else {
616                                 if (!sync_agent_delete_file(temp_filename_kept)) {
617                                         _DEBUG_ERROR("[sync_agent_write_file] deleting temp file fail.");
618                                         ret = 0;
619                                 }
620                         }
621                 }
622                 goto return_part;
623         }
624
625         _EXTERN_FUNC_EXIT;
626
627         return ret;
628
629  return_part:
630
631         if (fd_temp != NULL)
632                 fclose(fd_temp);
633         g_free(temp_filename_kept);
634         g_free(requested_filename_kept);
635         temp_filename_kept = NULL;
636         requested_filename_kept = NULL;
637         file_append_started = FALSE;
638
639         return ret;
640
641 /*
642         if( fs_is_existing(file_name) ) {
643                 fprintf(stderr, "[%s] Requested instance '%s' already exist.", __func__, file_name);
644                 return SYNC_AGENT_FSAPI_FALSE;
645         }
646
647         GError *gerror = NULL;
648
649         if( !g_file_set_contents(file_name, contents, length, &gerror) ) {
650                 fprintf(stderr, "[%s] g_file_set_contents error : %s\n", __func__, gerror->message);
651
652                 g_error_free(gerror);
653                 return SYNC_AGENT_FSAPI_FALSE;
654         }
655
656         return SYNC_AGENT_FSAPI_TRUE;
657 */
658 }
659
660 EXPORT_API sync_agent_fsapi_return_e sync_agent_write_whole_file(const char *file_name, const char *contents, unsigned long length, bool overwrite)
661 {
662         _EXTERN_FUNC_ENTER;
663
664         retvm_if(file_name == NULL, 0, "file_name paramter is NULL !!!");
665         retvm_if(contents == NULL, 0, "contents is NULL !!");
666
667         if (fs_is_existing(file_name)) {
668                 if (overwrite && !fs_is_directory(file_name)) {
669                         int result = sync_agent_delete_file(file_name);
670                         if (result == 0) {
671                                 _DEBUG_ERROR("[%s] sync_agent_delete_file() FAIL !!!.", __func__, file_name);
672                                 return SYNC_AGENT_FSAPI_FALSE;
673                         }
674                 } else {
675                         _DEBUG_ERROR("[%s] Requested instance '%s' already exist.", __func__, file_name);
676                         return SYNC_AGENT_FSAPI_FALSE;
677                 }
678         }
679
680         GError *gerror = NULL;
681
682         if (!g_file_set_contents(file_name, contents, length, &gerror)) {
683                 _DEBUG_ERROR("[%s] g_file_set_contents error : %s\n", __func__, gerror->message);
684
685                 g_error_free(gerror);
686                 return SYNC_AGENT_FSAPI_FALSE;
687         }
688
689         _EXTERN_FUNC_EXIT;
690
691         return SYNC_AGENT_FSAPI_TRUE;
692 }
693
694 EXPORT_API sync_agent_fsapi_return_e sync_agent_append_file(const char *file_name, const char *contents, unsigned long length, bool overwrite)
695 {
696         _EXTERN_FUNC_ENTER;
697
698         retvm_if(file_name == NULL, 0, "file_name paramter is NULL !!!");
699         retvm_if(contents == NULL, 0, "contents is NULL !!");
700
701         if (overwrite) {
702                 if (!sync_agent_delete_file(file_name)) {
703                         if (!fs_is_existing(file_name)) {
704                                 _DEBUG_ERROR("[%s] The file %s requested to delete for overwriting is not existing, so just continue.", __func__, file_name);
705                         } else {
706                                 if (fs_is_directory(file_name)) {
707                                         _DEBUG_ERROR("[%s] Can't overwrite because requested instance '%s' not a file.", __func__, file_name);
708                                         return SYNC_AGENT_FSAPI_FALSE;
709                                 } else {
710                                         _DEBUG_ERROR("[%s] FAILED to delete requested file '%s'.", __func__, file_name);
711                                         return SYNC_AGENT_FSAPI_FALSE;
712                                 }
713                         }
714                 }
715         }
716
717         FILE *fd = NULL;
718         int ret = 1;
719
720         fd = (FILE *) g_fopen(file_name, "ab");
721         if (fd == NULL) {
722                 _DEBUG_ERROR("[sync_agent_append_file] file open error.");
723                 ret = 0;
724                 goto return_part;
725         }
726
727         if (fwrite(contents, 1, length, fd) != length) {
728                 _DEBUG_ERROR("[%s] fwrite error '%s'.", __func__, file_name);
729                 ret = 0;
730                 goto return_part;
731         }
732
733         if (fsync(fileno(fd)) != 0)
734                 ret = 0;
735
736         _EXTERN_FUNC_EXIT;
737
738  return_part:
739
740         if (fd != NULL)
741                 fclose(fd);
742
743         _DEBUG_INFO("[%s] Returning..", __func__);
744         return ret;
745 }
746
747 /*
748  * Folder operation
749  */
750
751 EXPORT_API sync_agent_fsapi_return_e sync_agent_create_directory(const char *folder_name)
752 {
753         _EXTERN_FUNC_ENTER;
754
755         retvm_if(folder_name == NULL, 0, "folder_name paramter is NULL !!!");
756
757         if (fs_is_existing(folder_name)) {
758                 _DEBUG_ERROR("[%s] Requested instance '%s' already exist.\n", __func__, folder_name);
759                 return SYNC_AGENT_FSAPI_FALSE;
760         }
761
762         int ret = g_mkdir_with_parents(folder_name, 0755);
763         if (ret == -1) {
764                 _DEBUG_ERROR("[%s] g_mkdir error : %s\n", __func__, strerror(errno));
765                 return SYNC_AGENT_FSAPI_FALSE;
766         }
767
768         _EXTERN_FUNC_EXIT;
769
770         return SYNC_AGENT_FSAPI_TRUE;
771 }
772
773 EXPORT_API sync_agent_fsapi_return_e sync_agent_delete_directory(const char *folder_name, bool recursive)
774 {
775         _EXTERN_FUNC_ENTER;
776
777         retvm_if(folder_name == NULL, 0, "folder_name paramter is NULL !!!");
778
779         if (!fs_is_existing(folder_name) || !fs_is_directory(folder_name)) {
780                 _DEBUG_ERROR("[%s] Requested instance '%s' not exist, or not a directory.\n", __func__, folder_name);
781                 return SYNC_AGENT_FSAPI_FALSE;
782         }
783
784         GError *gerror = NULL;
785         GDir *dir = NULL;
786         int ret = 0;
787         char *path = NULL;
788         char *name = NULL;
789
790         if (recursive) {
791                 dir = g_dir_open(folder_name, 0, &gerror);
792                 if (dir == NULL) {
793                         _DEBUG_ERROR("[%s] g_dir_open error : %s\n", __func__, gerror->message);
794                         g_error_free(gerror);
795                         return SYNC_AGENT_FSAPI_FALSE;
796                 }
797
798                 name = (char *)g_dir_read_name(dir);
799
800                 for (; name; name = (char *)g_dir_read_name(dir)) {
801
802                         path = g_strdup_printf("%s/%s", folder_name, name);
803
804                         if (fs_is_directory(path)) {
805                                 if (!sync_agent_delete_directory(path, true))
806                                         return SYNC_AGENT_FSAPI_FALSE;
807                         } else {
808                                 if (!sync_agent_delete_file(path))
809                                         return SYNC_AGENT_FSAPI_FALSE;
810                         }
811                 }
812
813                 if (path != NULL)
814                         free(path);
815                 g_dir_close(dir);
816                 dir = NULL;
817         }
818
819         ret = g_rmdir(folder_name);
820         if (ret == -1) {
821                 _DEBUG_ERROR("[%s] g_rmdir error : %s\n", __func__, strerror(errno));
822                 return SYNC_AGENT_FSAPI_FALSE;
823         }
824
825         _EXTERN_FUNC_EXIT;
826
827         return SYNC_AGENT_FSAPI_TRUE;
828 }
829
830 EXPORT_API sync_agent_fsapi_return_e sync_agent_empty_directory_contents(const char *folder_name)
831 {
832         _EXTERN_FUNC_ENTER;
833
834         retvm_if(folder_name == NULL, 0, "folder_name paramter is NULL !!!");
835
836         if (!fs_is_existing(folder_name) || !fs_is_directory(folder_name)) {
837                 _DEBUG_ERROR("[%s] Requested instance '%s' not exist, or not a directory.\n", __func__, folder_name);
838                 return SYNC_AGENT_FSAPI_FALSE;
839         }
840
841         GError *gerror = NULL;
842         GDir *dir = NULL;
843         char *path = NULL;
844         char *name = NULL;
845
846         dir = g_dir_open(folder_name, 0, &gerror);
847         if (dir == NULL) {
848                 _DEBUG_ERROR("[%s] g_dir_open error : %s\n", __func__, gerror->message);
849                 g_error_free(gerror);
850                 return SYNC_AGENT_FSAPI_FALSE;
851         }
852
853         name = (char *)g_dir_read_name(dir);
854
855         for (; name; name = (char *)g_dir_read_name(dir)) {
856
857                 path = g_strdup_printf("%s/%s", folder_name, name);
858
859                 if (fs_is_directory(path)) {
860                         if (!sync_agent_delete_directory(path, true)) {
861                                 _DEBUG_ERROR("[%s] sync_agent_delete_directory error : %s\n", __func__, strerror(errno));
862                                 return SYNC_AGENT_FSAPI_FALSE;
863                         }
864                 } else {
865                         if (!sync_agent_delete_file(path)) {
866                                 _DEBUG_ERROR("[%s] sync_agent_delete_file error : %s\n", __func__, strerror(errno));
867                                 return SYNC_AGENT_FSAPI_FALSE;
868                         }
869                 }
870         }
871
872         if (path != NULL)
873                 free(path);
874         g_dir_close(dir);
875         dir = NULL;
876
877         _EXTERN_FUNC_EXIT;
878
879         return SYNC_AGENT_FSAPI_TRUE;
880 }
881
882 EXPORT_API sync_agent_fsapi_return_e sync_agent_rename_directory(const char *source, const char *dest)
883 {
884         _EXTERN_FUNC_ENTER;
885
886         retvm_if(source == NULL, 0, "source paramter is NULL !!!");
887         retvm_if(dest == NULL, 0, "dest paramter is NULL !!!");
888
889         if (!fs_is_existing(source) || !fs_is_directory(source) || fs_is_existing(dest)) {
890                 _DEBUG_ERROR("[%s] Requested source instance '%s' not exist or not a directory, or\n", __func__, source);
891                 _DEBUG_ERROR("[%s] requested dest instance '%s' already exist.\n", __func__, dest);
892                 return SYNC_AGENT_FSAPI_FALSE;
893         }
894
895         int ret = g_rename(source, dest);
896         if (ret == -1) {
897                 _DEBUG_ERROR("[%s] g_rename error : %s\n", __func__, strerror(errno));
898                 return SYNC_AGENT_FSAPI_FALSE;
899         }
900
901         _EXTERN_FUNC_EXIT;
902
903         return SYNC_AGENT_FSAPI_TRUE;
904 }
905
906 EXPORT_API sync_agent_fsapi_return_e sync_agent_get_directory_list(const char *folder_name, GSList ** list)
907 {
908         _EXTERN_FUNC_ENTER;
909
910         retvm_if(folder_name == NULL, 0, "folder_name paramter is NULL !!!");
911
912         if (!fs_is_existing(folder_name) || !fs_is_directory(folder_name)) {
913                 _DEBUG_ERROR("[%s] Requested instance '%s' not exist, or not a directory.\n", __func__, folder_name);
914                 return SYNC_AGENT_FSAPI_FALSE;
915         }
916
917         struct stat buf;
918         char *path = NULL;
919         char time[FS_MAX_TIME_STRING_BUF] = { 0 };
920         char *list_item = NULL;
921
922         GError *gerror = NULL;
923         GDir *dir = g_dir_open(folder_name, 0, &gerror);
924         if (dir == NULL) {
925                 _DEBUG_ERROR("[%s] g_dir_open error : %s\n", __func__, gerror->message);
926                 g_error_free(gerror);
927                 return SYNC_AGENT_FSAPI_FALSE;
928         }
929
930         const char *file_name = g_dir_read_name(dir);
931
932         for (; file_name; file_name = g_dir_read_name(dir)) {
933
934                 path = g_strdup_printf("%s/%s", folder_name, file_name);
935
936                 if (fs_is_directory(path)) {
937                         int ret = stat(path, &buf);
938                         if (ret == -1) {
939                                 _DEBUG_ERROR("[%s] g_stat error : %s\n", __func__, strerror(errno));
940                                 return SYNC_AGENT_FSAPI_FALSE;
941                         }
942
943                         fs_get_time_string(&buf.st_mtime, time);
944                         list_item = g_strdup_printf("%s,%ld,%s", file_name, (long)buf.st_nlink - 2, time);
945
946                         *list = g_slist_append(*list, list_item);
947                 }
948         }
949
950         free(path);
951         g_dir_close(dir);
952         dir = NULL;
953
954         _EXTERN_FUNC_EXIT;
955
956         return SYNC_AGENT_FSAPI_TRUE;
957
958 }
959
960 EXPORT_API void sync_agent_free_fs_list(GSList * list)
961 {
962         _EXTERN_FUNC_ENTER;
963
964         retm_if(list == NULL, "folder_name paramter is NULL !!!");
965
966         GSList *iter = NULL;
967
968         for (iter = list; iter != NULL; iter = g_slist_next(iter)) {
969                 g_free(iter->data);
970         }
971
972         g_slist_free(list);
973
974         _EXTERN_FUNC_EXIT;
975 }
976
977 EXPORT_API sync_agent_fsapi_return_e sync_agent_file_md5_validation(const char *file_path, const char *find_md5_word, bool * is_same)
978 {
979         _EXTERN_FUNC_ENTER;
980
981         retvm_if(file_path == NULL, 0, "file_path paramter is NULL !!!");
982         retvm_if(find_md5_word == NULL, 0, "find_md5_word paramter is NULL !!!");
983
984         int ret = 1;
985         unsigned char *real_md5_word = NULL;
986
987         _DEBUG_INFO("File_Path = %s\n", file_path);
988
989         /* get file hash key */
990         ret = fs_file_md5_hashkey(file_path, &real_md5_word);
991         if (ret != 1) {
992                 _DEBUG_ERROR("fs_file_md5_hashkey() Fail!!\n");
993                 goto return_part;
994         }
995
996         /* convert hex char to string (=> hash key) */
997         char szTmp_digest[256] = { 0, };
998         int k;
999         for (k = 0; k < 16; k++) {
1000                 szTmp_digest[k * 2] = _sync_str_to_hex_char((unsigned char)((real_md5_word[k] >> 4) & 0x0f));
1001                 szTmp_digest[k * 2 + 1] = _sync_str_to_hex_char((unsigned char)(real_md5_word[k] & 0x0f));
1002         }
1003
1004         _DEBUG_INFO("find_md5_word = %s\n", find_md5_word);
1005         _DEBUG_INFO("real_md5_word = %s\n", szTmp_digest);
1006
1007         /* compare read md5 checksum to file_md5_checksum */
1008         if (memcmp(find_md5_word, szTmp_digest, strlen(szTmp_digest))) {
1009                 _DEBUG_ERROR("MD5 Hash Keys are not equal.\n");
1010                 *is_same = false;
1011                 ret = 0;
1012                 goto return_part;
1013         }
1014
1015         _DEBUG_INFO("MD5 Hash Keys are equal.\n");
1016         *is_same = true;
1017
1018         _EXTERN_FUNC_EXIT;
1019
1020  return_part:
1021
1022         if (real_md5_word != NULL)
1023                 free(real_md5_word);
1024
1025         return ret;
1026 }
1027
1028 int fs_file_md5_hashkey(const char *file_path, unsigned char **hash_key)
1029 {
1030         _EXTERN_FUNC_ENTER;
1031
1032         retvm_if(file_path == NULL, 0, "file_path paramter is NULL !!!");
1033
1034         int ret = 1;
1035         *hash_key = NULL;
1036
1037         unsigned long full_file_size = 0;
1038         ret = sync_agent_get_file_size(file_path, &full_file_size);
1039         _DEBUG_INFO("full_file_size = %d\n", full_file_size);
1040
1041         /* get MD5 encryption Hash Key */
1042         char *required_contents = NULL;
1043         unsigned char *real_md5_word = (unsigned char *)calloc(16, sizeof(char));
1044         if (real_md5_word == NULL) {
1045                 _DEBUG_ERROR("CALLOC failed !!!");
1046                 ret = 0;
1047                 goto return_part;
1048         }
1049         bool isFinal = false;
1050         unsigned long read_file_size = 0;
1051
1052         sa_md5_context_s context;
1053
1054         sa_md5_init(&context);
1055
1056         while (isFinal == false) {
1057
1058                 ret = sync_agent_read_file(file_path, &required_contents, FS_BUFFER_SIZE, &read_file_size, &isFinal);
1059                 if (ret != 1) {
1060                         _DEBUG_ERROR("sync_agent_read_file() Fail\n");
1061                         goto return_part;
1062                 }
1063
1064                 _DEBUG_INFO("read_file_size = %d\n", read_file_size);
1065                 _DEBUG_INFO("isFinal = %d\n", isFinal);
1066                 sa_md5_update(&context, required_contents, read_file_size);
1067         }
1068         sa_md5_final(&context, real_md5_word);
1069
1070         /* print Hex char MD5 */
1071         int real_md5_length = strlen((const char *)real_md5_word);
1072         _DEBUG_INFO("real_md5_length = %d\n", real_md5_length);
1073         _DEBUG_INFO(" real md5 : ");
1074         int i = 0;
1075         for (; i < real_md5_length; ++i) {
1076                 _DEBUG_INFO("%02x", real_md5_word[i]);
1077         }
1078         _DEBUG_INFO("\n");
1079
1080         *hash_key = real_md5_word;
1081
1082         _DEBUG_INFO("Free Part");
1083         sync_agent_free_file(&required_contents);
1084
1085         _EXTERN_FUNC_EXIT;
1086
1087  return_part:
1088         return ret;
1089 }
1090
1091 static unsigned char _sync_str_to_hex_char(unsigned char hex)
1092 {
1093         _INNER_FUNC_ENTER;
1094
1095         if (0 <= (char)hex && (char)hex <= 9) {
1096                 _EXTERN_FUNC_EXIT;
1097                 return '0' + hex;
1098         } else {
1099                 if (10 <= (char)hex && (char)hex <= 15) {
1100                         _INNER_FUNC_EXIT;
1101                         return 'A' + hex - 10;
1102                 }
1103         }
1104
1105         _INNER_FUNC_EXIT;
1106
1107         return '?';
1108 }