To use hash value for file name. 41/44941/6 accepted/tizen/mobile/20150810.101549 accepted/tizen/tv/20150810.101748 accepted/tizen/wearable/20150810.101937 submit/tizen/20150810.072500
authorMyungki Lee <mk5004.lee@samsung.com>
Thu, 6 Aug 2015 11:36:19 +0000 (20:36 +0900)
committerSangyoon Jang <s89.jang@samsung.com>
Fri, 7 Aug 2015 02:20:06 +0000 (19:20 -0700)
Change-Id: I3e6b068853a2c4b3195928c4b29136bb572fd5ed
Signed-off-by: Myungki Lee <mk5004.lee@samsung.com>
include/app_preference_internal.h
preference/preference.c

index cb670fe..1092753 100644 (file)
@@ -57,6 +57,11 @@ extern "C" {
 #define PREFERENCE_ERROR_WRONG_TYPE      -3
 
 /**
+ * @brief Definition for PREFERENCE_ERROR_OUT_OF_MEMORY.
+ */
+#define PREFERENCE_ERROR_OUT_OF_MEMORY      -12
+
+/**
  * @brief Definition for PREFERENCE_ERROR_FILE_OPEN.
  */
 #define PREFERENCE_ERROR_FILE_OPEN       -21
index 8ae6dd5..98d4cfa 100644 (file)
@@ -33,6 +33,9 @@
 
 #include <sys/syscall.h>
 
+#ifdef PREFERENCE_TIMECHECK
+#include <sys/time.h>
+#endif
 
 #ifndef API
 #define API __attribute__ ((visibility("default")))
@@ -153,80 +156,74 @@ inline void _preference_keynode_free(keynode_t *keynode)
        }
 }
 
-int _preference_get_key_name(const char *keyfile, char *keyname)
+int _preference_get_key_name(const char *path, char **keyname)
 {
-       unsigned int i = 0;
-       char convert_key[PATH_MAX] = {0,};
-       guchar *key_name = NULL;
-       gsize key_path_len = 0;
+       int read_size = 0;
+       size_t keyname_len = 0;
+       char *convert_key = NULL;
+       FILE *fp = NULL;
 
-       strncpy(convert_key, keyfile, PATH_MAX - 1);
+       if( (fp = fopen(path, "r")) == NULL ) {
+               return PREFERENCE_ERROR_FILE_OPEN;
+       }
 
-       for (i = 0; i < strlen(convert_key); i++) {
-               switch (convert_key[i]) {
-               case PREF_KEYNAME_C_DOT:
-                       convert_key[i] = PREF_KEYNAME_C_PAD;
-                       break;
-               case PREF_KEYNAME_C_UNDERSCORE:
-                       convert_key[i] = PREF_KEYNAME_C_PLUS;
-                       break;
-               case PREF_KEYNAME_C_HYPHEN:
-                       convert_key[i] = PREF_KEYNAME_C_SLASH;
-                       break;
-               default:
-                       break;
-               }
+       read_size = fread((void *)&keyname_len, sizeof(int), 1, fp);
+       if (read_size <= 0) {
+               fclose(fp);
+               return PREFERENCE_ERROR_FILE_FREAD;
        }
 
-       key_name = g_base64_decode((const gchar *)convert_key, &key_path_len);
-       snprintf(keyname, PREFERENCE_KEY_PATH_LEN-1, "%s", key_name);
-       free(key_name);
+       convert_key = (char *)calloc(1, keyname_len+1);
+       if (convert_key == NULL) {
+               LOGE("memory alloc failed");
+               fclose(fp);
+               return PREFERENCE_ERROR_OUT_OF_MEMORY;
+       }
+
+       read_size = fread((void *)convert_key, keyname_len, 1, fp);
+       if (read_size <= 0) {
+               free(convert_key);
+               fclose(fp);
+               return PREFERENCE_ERROR_FILE_FREAD;
+       }
+
+       *keyname = convert_key;
+
+       fclose(fp);
 
        return PREFERENCE_ERROR_NONE;
 }
 
 int _preference_get_key_path(keynode_t *keynode, char *path)
 {
-       unsigned int i = 0;
        const char *key = NULL;
+       char *pref_dir_path = NULL;
+       gchar *convert_key;
        char *keyname = keynode->keyname;
 
-       if (!keyname) {
-               ERR("keyname is null");
+       if(!keyname) {
+               LOGE("keyname is null");
                return PREFERENCE_ERROR_WRONG_PREFIX;
        }
 
-       char *convert_key = NULL;
-       char *pref_dir_path = NULL;
-
-       convert_key = g_base64_encode((const guchar *)keyname, strlen(keyname));
-
        pref_dir_path = _preference_get_pref_dir_path();
        if (!pref_dir_path) {
                LOGE("_preference_get_pref_dir_path() failed.");
-               g_free(convert_key);
                return PREFERENCE_ERROR_IO_ERROR;
        }
 
-       for (i = 0; i < strlen(convert_key); i++) {
-               switch (convert_key[i]) {
-               case PREF_KEYNAME_C_PAD:
-                       convert_key[i] = PREF_KEYNAME_C_DOT;
-                       break;
-               case PREF_KEYNAME_C_PLUS:
-                       convert_key[i] = PREF_KEYNAME_C_UNDERSCORE;
-                       break;
-               case PREF_KEYNAME_C_SLASH:
-                       convert_key[i] = PREF_KEYNAME_C_HYPHEN;
-                       break;
-               default:
-                       break;
-               }
+       convert_key = g_compute_checksum_for_string(G_CHECKSUM_SHA1,
+                                                       keyname,
+                                                       strlen(keyname));
+       if (convert_key == NULL) {
+               LOGE("fail to convert");
+               return PREFERENCE_ERROR_IO_ERROR;
        }
 
        key = (const char*)convert_key;
 
        snprintf(path, PATH_MAX-1, "%s%s", pref_dir_path, key);
+
        g_free(convert_key);
 
        return PREFERENCE_ERROR_NONE;
@@ -474,6 +471,7 @@ static int _preference_set_key_filesys(keynode_t *keynode, int *io_errno)
        char err_buf[100] = { 0, };
        int is_write_error = 0;
        int retry_cnt = 0;
+       size_t keyname_len = 0;
 
 retry_open :
        errno = 0;
@@ -495,7 +493,7 @@ retry :
        func_ret = PREFERENCE_ERROR_NONE;
 
        ret = _preference_set_write_lock(fileno(fp));
-       if(ret == -1) {
+       if (ret == -1) {
                func_ret = PREFERENCE_ERROR_FILE_LOCK;
                err_no = errno;
                ERR("file(%s) lock owner(%d)",
@@ -504,11 +502,35 @@ retry :
                goto out_return;
        }
 
+       /* write keyname and size */
+       keyname_len = strlen(keynode->keyname);
+
+       ret = fwrite((void *)&keyname_len, sizeof(int), 1, fp);
+       if (ret <= 0) {
+               if (!errno) {
+                       LOGW("number of written items is 0. try again");
+                       errno = EAGAIN;
+               }
+               err_no = errno;
+               func_ret = PREFERENCE_ERROR_FILE_WRITE;
+               goto out_unlock;
+       }
+
+       ret = fwrite((void *)keynode->keyname, keyname_len, 1, fp);
+       if (ret <= 0) {
+               if (!errno) {
+                       LOGW("number of written items is 0. try again");
+                       errno = EAGAIN;
+               }
+               err_no = errno;
+               func_ret = PREFERENCE_ERROR_FILE_WRITE;
+               goto out_unlock;
+       }
+
        /* write key type */
        ret = fwrite((void *)&(keynode->type), sizeof(int), 1, fp);
-       if(ret <= 0)
-       {
-               if(!errno) {
+       if (ret <= 0) {
+               if (!errno) {
                        LOGW("number of written items is 0. try again");
                        errno = EAGAIN;
                }
@@ -518,34 +540,32 @@ retry :
        }
 
        /* write key value */
-       switch(keynode->type)
-       {
-               case PREFERENCE_TYPE_INT:
-                       ret = fwrite((void *)&(keynode->value.i), sizeof(int), 1, fp);
-                       if(ret <= 0) is_write_error = 1;
-                       break;
-               case PREFERENCE_TYPE_DOUBLE:
-                       ret = fwrite((void *)&(keynode->value.d), sizeof(double), 1, fp);
-                       if(ret <= 0) is_write_error = 1;
-                       break;
-               case PREFERENCE_TYPE_BOOLEAN:
-                       ret = fwrite((void *)&(keynode->value.b), sizeof(int), 1, fp);
-                       if(ret <= 0) is_write_error = 1;
-                       break;
-               case PREFERENCE_TYPE_STRING:
-                       ret = fprintf(fp,"%s",keynode->value.s);
-                       if(ret < strlen(keynode->value.s)) is_write_error = 1;
-                       if (ftruncate(fileno(fp), ret) == -1) {
-                               is_write_error = 1;
-                       }
-                       break;
-               default :
-                       func_ret = PREFERENCE_ERROR_WRONG_TYPE;
-                       goto out_unlock;
+       switch (keynode->type) {
+       case PREFERENCE_TYPE_INT:
+               ret = fwrite((void *)&(keynode->value.i), sizeof(int), 1, fp);
+               if (ret <= 0) is_write_error = 1;
+               break;
+       case PREFERENCE_TYPE_DOUBLE:
+               ret = fwrite((void *)&(keynode->value.d), sizeof(double), 1, fp);
+               if (ret <= 0) is_write_error = 1;
+               break;
+       case PREFERENCE_TYPE_BOOLEAN:
+               ret = fwrite((void *)&(keynode->value.b), sizeof(int), 1, fp);
+               if (ret <= 0) is_write_error = 1;
+               break;
+       case PREFERENCE_TYPE_STRING:
+               ret = fprintf(fp,"%s",keynode->value.s);
+               if (ret < strlen(keynode->value.s)) is_write_error = 1;
+               if (ftruncate(fileno(fp), ret) == -1)
+                       is_write_error = 1;
+               break;
+       default :
+               func_ret = PREFERENCE_ERROR_WRONG_TYPE;
+               goto out_unlock;
        }
-       if(is_write_error)
-       {
-               if(!errno) {
+
+       if (is_write_error) {
+               if (!errno) {
                        LOGW("number of written items is 0. try again");
                        errno = EAGAIN;
                }
@@ -558,20 +578,17 @@ retry :
 
 out_unlock :
        ret = _preference_set_unlock(fileno(fp));
-       if(ret == -1) {
+       if (ret == -1) {
                func_ret = PREFERENCE_ERROR_FILE_LOCK;
                err_no = errno;
                goto out_return;
        }
 
 out_return :
-       if (func_ret != PREFERENCE_ERROR_NONE)
-       {
+       if (func_ret != PREFERENCE_ERROR_NONE) {
                strerror_r(err_no, err_buf, 100);
-               if (_preference_check_retry_err(keynode, func_ret, err_no, PREFERENCE_OP_SET))
-               {
-                       if (retry_cnt < PREFERENCE_ERROR_RETRY_CNT)
-                       {
+               if (_preference_check_retry_err(keynode, func_ret, err_no, PREFERENCE_OP_SET)) {
+                       if (retry_cnt < PREFERENCE_ERROR_RETRY_CNT) {
                                WARN("_preference_set_key_filesys(%d-%s) step(%d) failed(%d / %s) retry(%d)", keynode->type, keynode->keyname, func_ret, err_no, err_buf, retry_cnt);
                                retry_cnt++;
                                usleep((retry_cnt)*PREFERENCE_ERROR_RETRY_SLEEP_UTIME);
@@ -580,15 +597,11 @@ out_return :
                                        goto retry;
                                else
                                        goto retry_open;
-                       }
-                       else
-                       {
+                       } else {
                                ERR("_preference_set_key_filesys(%d-%s) step(%d) faild(%d / %s) over the retry count.",
                                        keynode->type, keynode->keyname, func_ret, err_no, err_buf);
                        }
-               }
-               else
-               {
+               } else {
                        ERR("_preference_set_key_filesys(%d-%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
                }
        } else {
@@ -597,12 +610,10 @@ out_return :
                }
        }
 
-       if (fp)
-       {
-               if(func_ret == PREFERENCE_ERROR_NONE)
-               {
+       if (fp) {
+               if (func_ret == PREFERENCE_ERROR_NONE) {
                        ret = fdatasync(fileno(fp));
-                       if(ret == -1) {
+                       if (ret == -1) {
                                err_no = errno;
                                func_ret = PREFERENCE_ERROR_FILE_SYNC;
                        }
@@ -801,6 +812,7 @@ static int _preference_get_key_filesys(keynode_t *keynode, int* io_errno)
        FILE *fp = NULL;
        int retry_cnt = 0;
        int read_size = 0;
+       size_t keyname_len = 0;
 
 retry_open :
        errno = 0;
@@ -820,18 +832,35 @@ retry :
        func_ret = PREFERENCE_ERROR_NONE;
 
        ret = _preference_set_read_lock(fileno(fp));
-       if(ret == -1) {
+       if (ret == -1) {
                func_ret = PREFERENCE_ERROR_FILE_LOCK;
                err_no = errno;
                goto out_return;
        }
 
+       read_size = fread((void *)&keyname_len, sizeof(int), 1, fp);
+       if ((read_size <= 0) || (read_size > sizeof(int))) {
+               if(!ferror(fp)) {
+                       errno = ENODATA;
+               }
+               err_no = errno;
+               func_ret = PREFERENCE_ERROR_FILE_FREAD;
+               goto out_unlock;
+       }
+
+       ret = fseek(fp, keyname_len, SEEK_CUR);
+       if (ret) {
+               if(!ferror(fp)) {
+                       errno = ENODATA;
+               }
+               err_no = errno;
+               func_ret = PREFERENCE_ERROR_FILE_FREAD;
+               goto out_unlock;
+       }
 
-       /* read data type */
-       read_size = fread((void*)&type, sizeof(int), 1, fp);
-       if((read_size <= 0) || (read_size > sizeof(int))) {
+       read_size = fread((void *)&type, sizeof(int), 1, fp);
+       if (read_size <= 0) {
                if(!ferror(fp)) {
-                       LOGW("number of read items for type is 0 with false ferror. err : %d", errno);
                        errno = ENODATA;
                }
                err_no = errno;
@@ -846,8 +875,8 @@ retry :
                {
                        int value_int = 0;
                        read_size = fread((void*)&value_int, sizeof(int), 1, fp);
-                       if((read_size <= 0) || (read_size > sizeof(int))) {
-                               if(!ferror(fp)) {
+                       if ((read_size <= 0) || (read_size > sizeof(int))) {
+                               if (!ferror(fp)) {
                                        LOGW("number of read items for value is wrong. err : %d", errno);
                                }
                                err_no = errno;
@@ -863,8 +892,8 @@ retry :
                {
                        double value_dbl = 0;
                        read_size = fread((void*)&value_dbl, sizeof(double), 1, fp);
-                       if((read_size <= 0) || (read_size > sizeof(double))) {
-                               if(!ferror(fp)) {
+                       if ((read_size <= 0) || (read_size > sizeof(double))) {
+                               if (!ferror(fp)) {
                                        LOGW("number of read items for value is wrong. err : %d", errno);
                                }
                                err_no = errno;
@@ -880,8 +909,8 @@ retry :
                {
                        int value_int = 0;
                        read_size = fread((void*)&value_int, sizeof(int), 1, fp);
-                       if((read_size <= 0) || (read_size > sizeof(int))) {
-                               if(!ferror(fp)) {
+                       if ((read_size <= 0) || (read_size > sizeof(int))) {
+                               if (!ferror(fp)) {
                                        LOGW("number of read items for value is wrong. err : %d", errno);
                                }
                                err_no = errno;
@@ -901,10 +930,10 @@ retry :
 
                        while(fgets(file_buf, sizeof(file_buf), fp))
                        {
-                               if(value) {
+                               if (value) {
                                        value_size = value_size + strlen(file_buf);
                                        value = (char *) realloc(value, value_size);
-                                       if(value == NULL) {
+                                       if (value == NULL) {
                                                func_ret = PREFERENCE_ERROR_OUT_OF_MEMORY;
                                                break;
                                        }
@@ -912,7 +941,7 @@ retry :
                                } else {
                                        value_size = strlen(file_buf) + 1;
                                        value = (char *)malloc(value_size);
-                                       if(value == NULL) {
+                                       if (value == NULL) {
                                                func_ret = PREFERENCE_ERROR_OUT_OF_MEMORY;
                                                break;
                                        }
@@ -921,17 +950,17 @@ retry :
                                }
                        }
 
-                       if(ferror(fp)) {
+                       if (ferror(fp)) {
                                err_no = errno;
                                func_ret = PREFERENCE_ERROR_FILE_FGETS;
                        } else {
-                               if(value) {
+                               if (value) {
                                        _preference_keynode_set_value_string(keynode, value);
                                } else {
                                        _preference_keynode_set_value_string(keynode, "");
                                }
                        }
-                       if(value)
+                       if (value)
                                free(value);
 
                        break;
@@ -942,7 +971,7 @@ retry :
 
 out_unlock :
        ret = _preference_set_unlock(fileno(fp));
-       if(ret == -1) {
+       if (ret == -1) {
                func_ret = PREFERENCE_ERROR_FILE_LOCK;
                err_no = errno;
                goto out_return;
@@ -1285,14 +1314,16 @@ API int preference_remove_all(void)
        while ((dent = readdir(dir)))
        {
                const char *entry = dent->d_name;
-               char keyname[PREFERENCE_KEY_PATH_LEN] = {0,};
+               char *keyname = NULL;
                char path[PATH_MAX] = {0,};
 
                if (entry[0] == '.') {
                        continue;
                }
 
-               ret = _preference_get_key_name(entry, keyname);
+               snprintf(path, PATH_MAX-1, "%s%s", pref_dir_path, entry);
+
+               ret = _preference_get_key_name(path, &keyname);
                if (ret != PREFERENCE_ERROR_NONE) {
                        ERR("_preference_get_key_name() failed(%d)", ret);
                        _preference_keynode_free(pKeyNode);
@@ -1305,29 +1336,13 @@ API int preference_remove_all(void)
                        ERR("preference_unset_changed_cb() failed(%d)", ret);
                        _preference_keynode_free(pKeyNode);
                        closedir(dir);
+                       free(keyname);
                        return PREFERENCE_ERROR_IO_ERROR;
                }
 
-               ret = _preference_keynode_set_keyname(pKeyNode, keyname);
-               if (ret != PREFERENCE_ERROR_NONE) {
-                       ERR("set key name error");
-                       _preference_keynode_free(pKeyNode);
-                       closedir(dir);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-
-               ret = _preference_get_key_path(pKeyNode, path);
-               if (ret != PREFERENCE_ERROR_NONE) {
-                       ERR("_preference_get_key_path() failed(%d)", ret);
-                       _preference_keynode_free(pKeyNode);
-                       closedir(dir);
-                       return ret;
-               }
-
-       // delete
                do {
                        ret = remove(path);
-                       if(ret == -1) {
+                       if (ret == -1) {
                                ERR("preference_remove_all error: %d(%s)", errno, strerror(errno));
                                func_ret = PREFERENCE_ERROR_IO_ERROR;
                        } else {
@@ -1335,6 +1350,8 @@ API int preference_remove_all(void)
                                break;
                        }
                } while(err_retry--);
+
+               free(keyname);
        }
 
        _preference_keynode_free(pKeyNode);
@@ -1489,16 +1506,20 @@ API int preference_foreach_item(preference_item_cb callback, void *user_data)
 
        while((dent = readdir(dir))) {
                const char *entry = dent->d_name;
-               char keyname[PREFERENCE_KEY_PATH_LEN] = {0,};
+               char *keyname = NULL;
+               char path[PATH_MAX] = {0,};
 
                if (entry[0] == '.') {
                        continue;
                }
 
-               ret = _preference_get_key_name(entry, keyname);
+               snprintf(path, PATH_MAX-1, "%s%s", pref_dir_path, entry);
+
+               ret = _preference_get_key_name(path, &keyname);
                retv_if(ret != PREFERENCE_ERROR_NONE, ret);
 
                callback(keyname, user_data);
+               free(keyname);
        }
 
        closedir(dir);