2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.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
8 * http://floralicense.org/license/
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.
24 #include "mf-fs-util.h"
27 static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
28 static int __mf_fs_oper_sort_by_date_cb_O2R(const void *d1, const void *d2);
29 static int __mf_fs_oper_sort_by_name_cb_A2Z(const void *d1, const void *d2);
30 static int __mf_fs_oper_sort_by_type_cb_A2Z(const void *d1, const void *d2);
31 static int __mf_fs_oper_sort_by_size_cb_S2L(const void *d1, const void *d2);
32 static int __mf_fs_oper_sort_by_name_cb_Z2A(const void *d1, const void *d2);
33 static int __mf_fs_oper_sort_by_date_cb_R2O(const void *d1, const void *d2);
34 static int __mf_fs_oper_sort_by_type_cb_Z2A(const void *d1, const void *d2);
35 static int __mf_fs_oper_sort_by_size_cb_L2S(const void *d1, const void *d2);
37 /*********************
38 **Function name: mf_fs_oper_print_node
40 ** fsNodeInfo *pNode: the file system node information need to print
46 ** printf the file system node information for debug
48 *********************/
49 void mf_fs_oper_print_node(fsNodeInfo *pNode)
52 /*mf_debug("path is [%s]\nname is [%s]\ndate is [%s]\ntype is [%d]\nsize is [%u]\nextension is [%s]\n\n",pNode->path,
53 pNode->name,asctime(gmtime(&(pNode->date))),pNode->type,pNode->size, pNode->ext);
58 /*********************
59 **Function name: mf_fs_oper_get_file
61 ** const char *path: full path to get file name
64 ** const char*: file name
67 ** get file name from full path
69 *********************/
70 static const char *mf_fs_oper_get_file(const char *path)
77 if ((result = strrchr(path, '/'))) {
80 result = (char *)path;
85 /*********************
86 **Function name: mf_fs_oper_error
88 ** const char* src: source path
89 ** const char* dst: destination path
90 ** int check_option: check option
96 ** input parameter checking
98 *********************/
99 int mf_fs_oper_error(const char *src, const char *dst, int check_option)
101 if ((check_option & MF_ERROR_CHECK_SRC_ARG_VALID) && (src == NULL)) {
102 return MYFILE_ERR_SRC_ARG_INVALID;
104 if ((check_option & MF_ERROR_CHECK_DST_ARG_VALID) && (dst == NULL)) {
105 return MYFILE_ERR_DST_ARG_INVALID;
108 if ((check_option & MF_ERROR_CHECK_SRC_EXIST) && (!ecore_file_exists(src))) {
109 return MYFILE_ERR_SRC_NOT_EXIST;
111 if ((check_option & MF_ERROR_CHECK_DST_EXIST) && (!ecore_file_exists(dst))) {
112 return MYFILE_ERR_DST_NOT_EXIST;
115 if (check_option & MF_ERROR_CHECK_SRC_PATH_VALID) {
116 if (!ecore_file_is_dir(src)) {
117 if (mf_file_attr_is_right_file_path(src)) {
118 return MYFILE_ERR_INVALID_FILE_PATH;
121 if (mf_file_attr_is_right_dir_path(src)) {
122 return MYFILE_ERR_INVALID_DIR_PATH;
126 if (check_option & MF_ERROR_CHECK_DST_PATH_VALID) {
127 if (!ecore_file_is_dir(dst)) {
128 int ret = mf_file_attr_is_right_file_path(dst);
133 int ret = mf_file_attr_is_right_dir_path(dst);
140 if (check_option & MF_ERROR_CHECK_SRC_PARENT_DIR_EXIST) {
141 char *parent_path = NULL;
142 if (mf_file_attr_get_parent_path(src, &parent_path)) {
143 if (!ecore_file_exists(parent_path)) {
144 SAFE_FREE_CHAR(parent_path);
145 return MYFILE_ERR_DIR_NOT_FOUND;
148 SAFE_FREE_CHAR(parent_path);
151 if (check_option & MF_ERROR_CHECK_DST_PARENT_DIR_EXIST) {
152 char *parent_path = NULL;
153 if (mf_file_attr_get_parent_path(dst, &parent_path)) {
154 if (!ecore_file_exists(parent_path)) {
155 SAFE_FREE_CHAR(parent_path);
156 return MYFILE_ERR_DIR_NOT_FOUND;
159 SAFE_FREE_CHAR(parent_path);
162 if (check_option & MF_ERROR_CHECK_DUPLICATED) {
163 char *parent_path = NULL;
165 if (!mf_file_attr_get_parent_path(dst, &parent_path)) {
166 if (mf_file_attr_is_duplicated_name(parent_path, mf_fs_oper_get_file(dst))) {
167 SAFE_FREE_CHAR(parent_path);
168 return MYFILE_ERR_DUPLICATED_NAME;
170 SAFE_FREE_CHAR(parent_path);
172 SAFE_FREE_CHAR(parent_path);
173 return MYFILE_ERR_GET_PARENT_PATH_FAIL;
177 return MYFILE_ERR_NONE;
180 /*********************
181 **Function name: mf_fs_oper_read_dir
183 ** char *path: path which we need to read
184 ** Eina_List** dir_list: output parameter of dir list under specified path
185 ** Eina_List** file_list: output parameter of file list under specified path
191 ** read element under the specified path
193 *********************/
194 int mf_fs_oper_read_dir(const char *path, Eina_List ** dir_list, Eina_List ** file_list)
199 mf_retvm_if(path == NULL, MYFILE_ERR_INVALID_ARG, "path is null");
200 mf_retvm_if(dir_list == NULL, MYFILE_ERR_INVALID_ARG, "dir_list is null");
201 mf_retvm_if(file_list == NULL, MYFILE_ERR_INVALID_ARG, "file_list is null");
202 int option = MF_ERROR_CHECK_SRC_ARG_VALID | MF_ERROR_CHECK_SRC_EXIST | MF_ERROR_CHECK_SRC_PATH_VALID;
203 int ret = mf_fs_oper_error(path, NULL, option);
204 if (ret != MYFILE_ERR_NONE) {
208 pDir = opendir(path);
211 return MYFILE_ERR_DIR_OPEN_FAIL;
214 while ((ent = readdir(pDir)) != NULL) {
215 GString *childpath = NULL;
216 fsNodeInfo *pNode = NULL;
218 if (strncmp(ent->d_name, ".", strlen(".")) == 0 || strncmp(ent->d_name, "..", strlen("..")) == 0) {
222 if ((ent->d_type & DT_DIR) == 0 && (ent->d_type & DT_REG) == 0) {
225 if ((ent->d_type & DT_DIR) != 0) {
226 if ((strlen(path) == strlen(PHONE_FOLDER)) && (strcmp(path, PHONE_FOLDER) == 0)
227 && (strlen(ent->d_name) == strlen(DEBUG_FOLDER)) && (strcmp(ent->d_name, DEBUG_FOLDER) == 0)) {
232 pNode = (fsNodeInfo *) malloc(sizeof(fsNodeInfo));
237 memset(pNode, 0, sizeof(fsNodeInfo));
239 pNode->path = g_strdup(path);
241 pNode->name = g_strdup(ent->d_name);
243 if (ent->d_type & DT_DIR) {
244 pNode->type = FILE_TYPE_DIR;
245 } else if (ent->d_type & DT_REG) {
246 mf_file_attr_get_file_category(ent->d_name, &(pNode->type));
249 childpath = g_string_new(path);
250 if (childpath == NULL) {
256 g_string_append_printf(childpath, "/%s", ent->d_name);
257 mf_file_attr_get_file_stat(childpath->str, &pNode);
258 if (pNode->type == FILE_TYPE_DIR) {
259 *dir_list = eina_list_append(*dir_list, pNode);
261 ret = mf_file_attr_get_file_ext(childpath->str, &pNode->ext);
262 if (ret != MYFILE_ERR_NONE) {
265 *file_list = eina_list_append(*file_list, pNode);
268 g_string_free(childpath, TRUE);
272 return MYFILE_ERR_NONE;
276 static int __mf_fs_oper_sort_by_priority(const void *d1, const void *d2, int sequence_type)
279 switch(sequence_type) {
280 case MF_SORT_BY_PRIORITY_TYPE_A2Z:
281 ret = __mf_fs_oper_sort_by_date_cb_O2R(d1, d2);
283 ret = __mf_fs_oper_sort_by_size_cb_S2L(d1, d2);
285 ret = __mf_fs_oper_sort_by_name_cb_A2Z(d1, d2);
289 case MF_SORT_BY_PRIORITY_TYPE_Z2A:
290 ret = __mf_fs_oper_sort_by_date_cb_R2O(d1, d2);
292 ret = __mf_fs_oper_sort_by_size_cb_L2S(d1, d2);
294 ret = __mf_fs_oper_sort_by_name_cb_Z2A(d1, d2);
298 case MF_SORT_BY_PRIORITY_DATE_O2R:
299 ret = __mf_fs_oper_sort_by_size_cb_S2L(d1, d2);
301 ret = __mf_fs_oper_sort_by_name_cb_A2Z(d1, d2);
304 case MF_SORT_BY_PRIORITY_DATE_R2O:
305 ret = __mf_fs_oper_sort_by_size_cb_L2S(d1, d2);
307 ret = __mf_fs_oper_sort_by_name_cb_Z2A(d1, d2);
310 case MF_SORT_BY_PRIORITY_SIZE_S2L:
311 ret = __mf_fs_oper_sort_by_name_cb_A2Z(d1, d2);
313 case MF_SORT_BY_PRIORITY_SIZE_L2S:
314 ret = __mf_fs_oper_sort_by_name_cb_Z2A(d1, d2);
321 /*********************
322 **Function name: __sort_by_name_cb
324 ** const void *d1: node1 to compare
325 ** const void *d2: node2 to compare
333 ** sort the list order by the Assic table
336 *********************/
337 static int __mf_fs_oper_sort_by_name_cb_A2Z(const void *d1, const void *d2)
339 fsNodeInfo *txt1 = (fsNodeInfo *) d1;
340 fsNodeInfo *txt2 = (fsNodeInfo *) d2;
345 if (!txt1 || !txt1->name) {
348 if (!txt2 || !txt2->name) {
352 name1 = g_ascii_strdown(txt1->name, strlen(txt1->name));
356 name2 = g_ascii_strdown(txt2->name, strlen(txt2->name));
362 result = g_strcmp0(name1, name2);
372 /*********************
373 **Function name: __sort_by_date_cb
375 ** const void *d1: node1 to compare
376 ** const void *d2: node2 to compare
384 ** sort the list order by the later created the later shown
385 *********************/
386 static int __mf_fs_oper_sort_by_date_cb_O2R(const void *d1, const void *d2)
389 fsNodeInfo *time1 = (fsNodeInfo *) d1;
390 fsNodeInfo *time2 = (fsNodeInfo *) d2;
399 if (time1->date > time2->date) {
401 } else if (time1->date < time2->date) {
408 ret = __mf_fs_oper_sort_by_priority(d1, d2, MF_SORT_BY_PRIORITY_DATE_O2R);
413 /*********************
414 **Function name: __sort_by_type_cb
416 ** const void *d1: node1 to compare
417 ** const void *d2: node2 to compare
425 ** sort the list order by the category type value
426 *********************/
427 static int __mf_fs_oper_sort_by_type_cb_A2Z(const void *d1, const void *d2)
429 fsNodeInfo *type1 = (fsNodeInfo *) d1;
430 fsNodeInfo *type2 = (fsNodeInfo *) d2;
435 if (type1 == NULL || type1->ext == NULL) {
439 if (type2 == NULL || type2->ext == NULL) {
442 ext1 = g_ascii_strdown(type1->ext, strlen(type1->ext));
446 ext2 = g_ascii_strdown(type2->ext, strlen(type2->ext));
452 result = g_strcmp0(ext1, ext2);
460 result = __mf_fs_oper_sort_by_priority(d1, d2, MF_SORT_BY_PRIORITY_TYPE_A2Z);
466 /*order: the one with smaller size will be shown earlier*/
467 /*********************
468 **Function name: __sort_by_name_cb
470 ** const void *d1: node1 to compare
471 ** const void *d2: node2 to compare
479 ** sort the list order by size, rule is the smaller the later shown
480 *********************/
481 static int __mf_fs_oper_sort_by_size_cb_S2L(const void *d1, const void *d2)
484 fsNodeInfo *size1 = (fsNodeInfo *) d1;
485 fsNodeInfo *size2 = (fsNodeInfo *) d2;
495 if (size1->size > size2->size) {
497 } else if (size1->size < size2->size) {
504 ret = __mf_fs_oper_sort_by_priority(d1, d2, MF_SORT_BY_PRIORITY_SIZE_S2L);
509 /*********************
510 **Function name: __mf_fs_oper_sort_by_name_cb_Z2A
512 ** const void *d1: node1 to compare
513 ** const void *d2: node2 to compare
520 ** sort the list order by the Assic table
523 *********************/
524 static int __mf_fs_oper_sort_by_name_cb_Z2A(const void *d1, const void *d2)
526 fsNodeInfo *txt1 = (fsNodeInfo *) d1;
527 fsNodeInfo *txt2 = (fsNodeInfo *) d2;
531 if (!txt1 || !txt1->name) {
534 if (!txt2 || !txt2->name) {
537 result = strcasecmp(txt1->name, txt2->name);
546 /*********************
547 **Function name: __sort_by_date_cb
549 ** const void *d1: node1 to compare
550 ** const void *d2: node2 to compare
558 ** sort the list order by the later created the later shown
559 *********************/
560 static int __mf_fs_oper_sort_by_date_cb_R2O(const void *d1, const void *d2)
563 fsNodeInfo *time1 = (fsNodeInfo *) d1;
564 fsNodeInfo *time2 = (fsNodeInfo *) d2;
572 if (time1->date > time2->date) {
574 } else if (time1->date < time2->date) {
581 ret = __mf_fs_oper_sort_by_priority(d1, d2, MF_SORT_BY_PRIORITY_DATE_R2O);
586 /*********************
587 **Function name: __sort_by_type_cb
589 ** const void *d1: node1 to compare
590 ** const void *d2: node2 to compare
598 ** sort the list order by the category type value
599 *********************/
600 static int __mf_fs_oper_sort_by_type_cb_Z2A(const void *d1, const void *d2)
602 fsNodeInfo *type1 = (fsNodeInfo *) d1;
603 fsNodeInfo *type2 = (fsNodeInfo *) d2;
608 if (type1 == NULL || type1->ext == NULL) {
612 if (type2 == NULL || type2->ext == NULL) {
616 ext1 = g_ascii_strdown(type1->ext, strlen(type1->ext));
620 ext2 = g_ascii_strdown(type2->ext, strlen(type2->ext));
626 result = g_strcmp0(ext1, ext2);
632 result = __mf_fs_oper_sort_by_priority(d1, d2, MF_SORT_BY_PRIORITY_TYPE_Z2A);
638 /*order: the one with smaller size will be shown earlier*/
639 /*********************
640 **Function name: __sort_by_name_cb
642 ** const void *d1: node1 to compare
643 ** const void *d2: node2 to compare
651 ** sort the list order by size, rule is the smaller the later shown
652 *********************/
653 static int __mf_fs_oper_sort_by_size_cb_L2S(const void *d1, const void *d2)
656 fsNodeInfo *size1 = (fsNodeInfo *) d1;
657 fsNodeInfo *size2 = (fsNodeInfo *) d2;
667 if (size1->size > size2->size) {
669 } else if (size1->size < size2->size) {
676 ret = __mf_fs_oper_sort_by_priority(d1, d2, MF_SORT_BY_PRIORITY_SIZE_L2S);
681 /*********************
682 **Function name: mf_fs_oper_sort_list
684 ** Eina_List **list: the list we need to sort
685 ** int sort_opt: sort option
691 ** sort the list order by sort option with the call back
692 *********************/
693 void mf_fs_oper_sort_list(Eina_List **list, int sort_opt)
695 Eina_Compare_Cb sort_func = NULL;
697 fsNodeInfo *data = NULL;
702 case MYFILE_SORT_BY_NAME_A2Z:
703 sort_func = __mf_fs_oper_sort_by_name_cb_A2Z;
705 case MYFILE_SORT_BY_TYPE_A2Z:
706 sort_func = __mf_fs_oper_sort_by_type_cb_A2Z;
708 case MYFILE_SORT_BY_SIZE_S2L:
709 sort_func = __mf_fs_oper_sort_by_size_cb_S2L;
711 case MYFILE_SORT_BY_DATE_O2R:
712 sort_func = __mf_fs_oper_sort_by_date_cb_O2R;
714 case MYFILE_SORT_BY_NAME_Z2A:
715 sort_func = __mf_fs_oper_sort_by_name_cb_Z2A;
717 case MYFILE_SORT_BY_TYPE_Z2A:
718 sort_func = __mf_fs_oper_sort_by_type_cb_Z2A;
720 case MYFILE_SORT_BY_SIZE_L2S:
721 sort_func = __mf_fs_oper_sort_by_size_cb_L2S;
723 case MYFILE_SORT_BY_DATE_R2O:
724 sort_func = __mf_fs_oper_sort_by_date_cb_R2O;
727 sort_func = __mf_fs_oper_sort_by_type_cb_A2Z;
730 EINA_LIST_FOREACH(*list, l, data) {
731 mf_fs_oper_print_node(data);
733 *list = eina_list_sort(*list, eina_list_count(*list), sort_func);
734 EINA_LIST_FOREACH(*list, l, data) {
735 mf_fs_oper_print_node(data);
740 /*********************
741 **Function name: mf_fs_oper_create_dir
743 ** const char *file: dir need to be operation
750 *********************/
751 int mf_fs_oper_create_dir(const char *dir)
753 int option = MF_ERROR_CHECK_SRC_ARG_VALID | MF_ERROR_CHECK_DUPLICATED;
754 int ret = mf_fs_oper_error(dir, dir, option);
760 ret = mf_file_attr_is_right_dir_path(dir);
766 if (mkdir(dir, default_mode) < 0) {
767 return MYFILE_ERR_DIR_CREATE_FAIL;
769 return MYFILE_ERR_NONE;
772 /*********************
773 **Function name: mf_fs_oper_rename_file
775 ** const char *src: source file need to rename
776 ** const char *dst: destination file which is to be renamed
784 *********************/
785 int mf_fs_oper_rename_file(const char *src, const char *dst)
788 int option = MF_ERROR_CHECK_SRC_ARG_VALID | MF_ERROR_CHECK_DST_ARG_VALID |
789 MF_ERROR_CHECK_SRC_EXIST | MF_ERROR_CHECK_DST_PATH_VALID |
790 MF_ERROR_CHECK_SRC_PATH_VALID | MF_ERROR_CHECK_SRC_PATH_VALID | MF_ERROR_CHECK_DST_PARENT_DIR_EXIST | MF_ERROR_CHECK_DUPLICATED;
791 int ret = mf_fs_oper_error(src, dst, option);
797 mf_debug("src is %s\ndst is %s\n", src, dst);
798 if (rename(src, dst)) {
799 return MYFILE_ERR_RENAME_FAIL;
801 return MYFILE_ERR_NONE;