#include <sys/stat.h>
#include <gmodule.h>
#include <limits.h>
+#include <regex.h>
#include "log.h"
#include "cleanup.h"
return -1;
}
-static int remove_path(const char *path, GList *except)
+static int remove_dir(const char *path, GList *except)
{
if (!path)
return -EINVAL;
return 0;
}
-static int cleanup_recursive(const char *path, GList *except)
+static int remove_oldfile(const char *path)
+{
+ regex_t regex;
+ int ret = 0;
+
+ if (!path)
+ return -EINVAL;
+
+ ret = regcomp(®ex, "\\.[0-9]+$", REG_EXTENDED);
+ if (ret)
+ return -EINVAL;
+
+ if (!regexec(®ex, path, 0, NULL, 0)) {
+ if(remove(path) != 0) {
+ _E("Failed to remove(%s): %d", path, errno);
+ ret = -errno;
+ } else
+ _D("Remove (%s)", path);
+ }
+ regfree(®ex);
+
+ return ret;
+}
+
+static int cleanup_recursive(const char *path, GList *except, int target)
{
DIR *dir = NULL;
struct dirent *dent;
}
snprintf(sub_path, PATH_MAX, "%s/%s", path, dent->d_name);
- ret = cleanup_recursive(sub_path, except);
+ ret = cleanup_recursive(sub_path, except, (target == CLEANUP_TARGET_OLDFILE)? target: CLEANUP_TARGET_ALL);
if (ret != 0)
break;
}
closedir(dir);
- if (!ret)
- ret = remove_path(path, except);
- } else
+ if (!ret && (target == CLEANUP_TARGET_ALL))
+ ret = remove_dir(path, except);
+ } else if (target == CLEANUP_TARGET_OLDFILE)
+ remove_oldfile(path);
+ else
REMOVE(path);
return ret;
list_config = get_cleanup_config(request->cleanup_mode);
for (list= g_list_first(list_config); NULL != list; list = g_list_next(list)) {
config = list->data;
+ _D("config path:%s, target:%d", config->path, config->target);
if (request->level <= config->level)
- cleanup_recursive(config->path, config->exclusion_list);
+ cleanup_recursive(config->path, config->exclusion_list, config->target);
}
-
remove_request_queue(request);
}
cleanup_th = 0;
else if (path_id == TZ_SYS_USER)
type = CLEANUP_TYPE_USER;
else {
- _D("Not supported path type: %d", path_id);
+ _D("Not supported path type: %s", tzplatform_getname(path_id));
return ;
}
#include <unistd.h>
#include <stdio.h>
+#include <stdbool.h>
#include <json-c/json.h>
#include <tzplatform_config.h>
"normal"
};
+char *cleanup_target_str[] = {
+ "all",
+ "file",
+ "oldfile"
+};
+
#define DEF_CLEANUP_CONFIG_FILE "/etc/storaged/cleanup-storage.conf"
#define RESULT(ret, val) \
{ \
*ret = val; \
}
+#define FREE(x) \
+{ \
+ if (x) \
+ free(x); \
+ x = NULL; \
+}
+
static GList *cleanup_list_system = NULL;
static GList *cleanup_list_user = NULL;
struct cleanup_config *item = data;
if (item->path) {
- free(item->path);
+ free((void *)item->path);
item->path = NULL;
}
}
}
-static int get_config_string_field(struct json_object *root, const char *key, char** value)
+static int get_config_string_field(struct json_object *root, const char *key, const char** value, bool optional)
{
struct json_object *node = NULL;
const char *node_value;
if (!json_object_object_get_ex(root, key, &node)) {
- _D("Config doesn't contain path param.");
- return 0;
+ if (optional)
+ _D("Config doesn't contain '%s' param.", key);
+ else
+ _E("Config doesn't contain '%s' param.", key);
+
+ return (optional)? 0: -EINVAL;
}
if (!json_object_is_type(node, json_type_string)) {
return 0;
}
-static GList *get_config_array_field(struct json_object *root, const char *key, int *ret)
+static GList *get_config_array_field(struct json_object *root, const char *key, int *ret, bool optional)
{
struct json_object *node = NULL, *obj;
int i, len;
GList *list = NULL;
if (!json_object_object_get_ex(root, key, &node)) {
- _D("Config doesn't contain '%s' param.", key);
- RESULT(ret, 0);
+ if (optional)
+ _D("Config doesn't contain '%s' param.", key);
+ else
+ _E("Config doesn't contain '%s' param.", key);
+
+ RESULT(ret, (optional)? 0: -EINVAL);
return NULL;
}
return -EINVAL;
for (i = 0; i< CLEANUP_LEVEL_NONE; i++) {
- if (strcmp(level_str, cleanup_level_str[i]) == 0)
+ if (strcasecmp(level_str, cleanup_level_str[i]) == 0) {
+ ret = i;
break;
+ }
}
- if (i < CLEANUP_LEVEL_NONE)
- ret = i;
+ return ret;
+}
+
+static int get_cleanup_target(const char *target_str)
+{
+ int ret = -EINVAL;
+ int i;
+
+ if (target_str == NULL)
+ return -EINVAL;
+
+ for (i = 0; i< CLEANUP_TARGET_END; i++) {
+ if (strcasecmp(target_str, cleanup_target_str[i]) == 0) {
+ ret = i;
+ break;
+ }
+ }
return ret;
}
return -EINVAL;
}
- if (get_config_string_field(obj, "level", &temp) != 0) {
- _E("There is no level node.");
- return -EINVAL;
+ if ((ret = get_config_string_field(obj, "level", (const char **)&temp, false)) != 0) {
+ return ret;
}
item->level = get_cleanup_level(temp);
- free(temp);
+ FREE(temp);
if (item->level < 0) {
_E("Invalid level value.");
return -EINVAL;
}
- if (get_config_string_field(obj, "path", &item->path) != 0)
- return -EINVAL;
+ if ((ret = get_config_string_field(obj, "path", &item->path, false)) != 0)
+ return ret;
- //todo.
- //check duplicated path
+ if ((ret = get_config_string_field(obj, "target", (const char **)&temp, true)) != 0) {
+ return ret;
+ }
+
+ if (temp) {
+ item->target = get_cleanup_target(temp);
+ if((item->target < CLEANUP_TARGET_ALL) || (item->target >= CLEANUP_TARGET_END))
+ item->target = CLEANUP_TARGET_ALL;
+ FREE(temp);
+ } else {
+ //_D("Use default 'target' : ALL");
+ item->target = CLEANUP_TARGET_ALL;
+ }
- item->exclusion_list = get_config_array_field(obj, "except", &ret);
+ item->exclusion_list = get_config_array_field(obj, "except", &ret, true);
if (ret != 0)
return -EINVAL;
{
"level":"critical",
"path":"/opt/val/test",
+ "target":"all",
"except":[
"/opt/val/test/except1",
"/opt/val/test/except2"
],
"/opt/usr":[
{
- "level":"full",
- "path":"/opt/usr/logtest"
+ "level":"warning",
+ "path":"/opt/usr/etc/test/remain_root",
+ "target":"file"
},
{
- "level":"full",
- "path":"/opt/usr/etc/test"
+ "level":"warning",
+ "path":"/opt/usr/etc/test/journal",
+ "target":"all",
+ "except":[
+ "/opt/usr/etc/test/journal/except_dir",
+ "/opt/usr/etc/test/journal/except_file"
+ ]
},
{
- "level":"full",
- "path":"/opt/usr/etc/test_crash"
+ "level":"warning",
+ "path":"/opt/usr/etc/test/delete"
},
{
"level":"critical",
- "path":"/opt/usr/data/test_GL"
+ "path":"/opt/usr/etc/test/critical"
+ },
+ {
+ "level":"warning",
+ "path":"/opt/usr/etc/test/log",
+ "target":"oldfile",
+ "except":[
+ "/opt/usr/etc/test/log/exceptlog.1"
+ ]
}
]
}