summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMyungki Lee <mk5004.lee@samsung.com>2015-08-06 20:36:19 +0900
committerSangyoon Jang <s89.jang@samsung.com>2015-08-06 19:20:06 -0700
commit0c228ce392d1ccd898788c57afaf623c2316f46c (patch)
tree959dded5cf00dc96a7ed9f48e59143fd235866e1
parent5e2d56ca587cbaf84e96ba81abb3e85eca25b05c (diff)
downloadapplication-0c228ce392d1ccd898788c57afaf623c2316f46c.tar.gz
application-0c228ce392d1ccd898788c57afaf623c2316f46c.tar.bz2
application-0c228ce392d1ccd898788c57afaf623c2316f46c.zip
Change-Id: I3e6b068853a2c4b3195928c4b29136bb572fd5ed Signed-off-by: Myungki Lee <mk5004.lee@samsung.com>
-rw-r--r--include/app_preference_internal.h5
-rw-r--r--preference/preference.c291
2 files changed, 161 insertions, 135 deletions
diff --git a/include/app_preference_internal.h b/include/app_preference_internal.h
index cb670fe..1092753 100644
--- a/include/app_preference_internal.h
+++ b/include/app_preference_internal.h
@@ -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
diff --git a/preference/preference.c b/preference/preference.c
index 8ae6dd5..98d4cfa 100644
--- a/preference/preference.c
+++ b/preference/preference.c
@@ -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);