Sync with the latest code of phone profile
[platform/framework/web/data-provider-master.git] / src / util.c
index 690df7e..fc07d5b 100644 (file)
@@ -1,11 +1,11 @@
 /*
- * Copyright 2012  Samsung Electronics Co., Ltd
+ * Copyright 2013  Samsung Electronics Co., Ltd
  *
- * Licensed under the Flora License, Version 1.0 (the "License");
+ * Licensed under the Flora License, Version 1.1 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * http://www.tizenopensource.org/license
+ * http://floralicense.org/license/
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * limitations under the License.
  */
 
+#define _GNU_SOURCE
+
 #include <stdio.h>
 #include <sys/time.h>
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
 #include <stdlib.h>
-#include <sys/statvfs.h>
+#include <sys/vfs.h>
 #include <sys/types.h>
 #include <dirent.h>
+#include <ctype.h>
+#include <sys/statvfs.h>
+#include <sys/mount.h>
 
+#include <sys/smack.h>
 #include <dlog.h>
 #include <Eina.h>
 #include <Ecore.h>
+#include <livebox-errno.h>
 
 #include "util.h"
 #include "debug.h"
 #include "conf.h"
 
+static struct info {
+       int emergency_mounted;
+} s_info = {
+       .emergency_mounted = 0,
+};
+
 int errno;
 
 HAPI unsigned long util_string_hash(const char *str)
 {
        unsigned long ret = 0;
 
-       while (*str)
+       while (*str) {
                ret += (unsigned long)(*str++);
+       }
 
        ret %= 371773;
        return ret;
@@ -47,8 +61,10 @@ HAPI unsigned long util_string_hash(const char *str)
 
 HAPI double util_timestamp(void)
 {
+#if defined(_USE_ECORE_TIME_GET)
+       return ecore_time_get();
+#else
        struct timeval tv;
-
        if (gettimeofday(&tv, NULL) < 0) {
                static unsigned long internal_count = 0;
                ErrPrint("failed to get time of day: %s\n", strerror(errno));
@@ -57,6 +73,7 @@ HAPI double util_timestamp(void)
        }
 
        return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
+#endif
 }
 
 HAPI int util_check_ext(const char *filename, const char *check_ptr)
@@ -65,13 +82,14 @@ HAPI int util_check_ext(const char *filename, const char *check_ptr)
 
        name_len = strlen(filename);
        while (--name_len >= 0 && *check_ptr) {
-               if (filename[name_len] != *check_ptr)
-                       return -EINVAL;
+               if (filename[name_len] != *check_ptr) {
+                       return LB_STATUS_ERROR_INVALID;
+               }
 
                check_ptr ++;
        }
 
-       return 0;
+       return LB_STATUS_SUCCESS;
 }
 
 static inline int check_native_livebox(const char *pkgname)
@@ -86,18 +104,18 @@ static inline int check_native_livebox(const char *pkgname)
        path = malloc(len + 1);
        if (!path) {
                ErrPrint("Heap: %s\n", strerror(errno));
-               return -ENOMEM;
+               return LB_STATUS_ERROR_MEMORY;
        }
 
        snprintf(path, len, "%s%s/libexec/liblive-%s.so", ROOT_PATH, pkgname, pkgname);
        if (access(path, F_OK | R_OK) != 0) {
                ErrPrint("%s is not a valid package\n", pkgname);
                DbgFree(path);
-               return -EINVAL;
+               return LB_STATUS_ERROR_INVALID;
        }
 
        DbgFree(path);
-       return 0;
+       return LB_STATUS_SUCCESS;
 }
 
 static inline int check_web_livebox(const char *pkgname)
@@ -111,31 +129,32 @@ static inline int check_web_livebox(const char *pkgname)
        path = malloc(len + 1);
        if (!path) {
                ErrPrint("Heap: %s\n", strerror(errno));
-               return -ENOMEM;
+               return LB_STATUS_ERROR_MEMORY;
        }
 
        snprintf(path, len, "/opt/usr/apps/%s/res/wgt/livebox/index.html", pkgname);
        if (access(path, F_OK | R_OK) != 0) {
                ErrPrint("%s is not a valid package\n", pkgname);
                DbgFree(path);
-               return -EINVAL;
+               return LB_STATUS_ERROR_INVALID;
        }
 
        DbgFree(path);
-       return 0;
+       return LB_STATUS_SUCCESS;
 }
 
 HAPI int util_validate_livebox_package(const char *pkgname)
 {
        if (!pkgname) {
                ErrPrint("Invalid argument\n");
-               return -EINVAL;
+               return LB_STATUS_ERROR_INVALID;
        }
 
-       if (!check_native_livebox(pkgname) || !check_web_livebox(pkgname))
-               return 0;
+       if (!check_native_livebox(pkgname) || !check_web_livebox(pkgname)) {
+               return LB_STATUS_SUCCESS;
+       }
 
-       return -EINVAL;
+       return LB_STATUS_ERROR_INVALID;
 }
 
 HAPI int util_unlink(const char *filename)
@@ -144,25 +163,29 @@ HAPI int util_unlink(const char *filename)
        int desclen;
        int ret;
 
+       if (!filename) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
        desclen = strlen(filename) + 6; /* .desc */
        descfile = malloc(desclen);
        if (!descfile) {
                ErrPrint("Heap: %s\n", strerror(errno));
-               return -ENOMEM;
+               return LB_STATUS_ERROR_MEMORY;
        }
 
        ret = snprintf(descfile, desclen, "%s.desc", filename);
        if (ret < 0) {
                ErrPrint("Error: %s\n", strerror(errno));
                DbgFree(descfile);
-               return -EFAULT;
+               return LB_STATUS_ERROR_FAULT;
        }
 
        (void)unlink(descfile);
        DbgFree(descfile);
        (void)unlink(filename);
 
-       return 0;
+       return LB_STATUS_SUCCESS;
 }
 
 HAPI char *util_slavename(void)
@@ -178,29 +201,35 @@ HAPI const char *util_basename(const char *name)
 {
        int length;
        length = name ? strlen(name) : 0;
-       if (!length)
+       if (!length) {
                return ".";
+       }
 
        while (--length > 0 && name[length] != '/');
 
        return length <= 0 ? name : (name + length + (name[length] == '/'));
 }
 
-HAPI unsigned long util_free_space(const char *path)
+/*!
+ * Return size of stroage in Bytes unit.
+ */
+HAPI unsigned long long util_free_space(const char *path)
 {
        struct statvfs st;
-       unsigned long space;
+       unsigned long long space;
 
        if (statvfs(path, &st) < 0) {
                ErrPrint("statvfs: %s\n", strerror(errno));
                return 0lu;
        }
 
-       space = st.f_bsize * st.f_bfree;
+       space = (unsigned long long)st.f_bsize * (unsigned long long)st.f_bavail;
+       DbgPrint("Available size: %llu, f_bsize: %lu, f_bavail: %lu\n", space, st.f_bsize, st.f_bavail);
        /*!
         * \note
         * Must have to check the overflow
         */
+
        return space;
 }
 
@@ -220,104 +249,107 @@ static inline char *extend_heap(char *buffer, int *sz, int incsz)
 
 HAPI char *util_replace_string(const char *src, const char *pattern, const char *replace)
 {
-       char *ret;
-       int src_idx;
-       int pattern_idx;
-       int src_rollback_idx;
-       int ret_rollback_idx;
-       int ret_idx;
-       int target_idx;
-       int bufsz;
-       int incsz;
-       int matched;
-
-       bufsz = strlen(src);
-       incsz = bufsz + 1; /* Including the NULL byte */
-       ret = malloc(bufsz + 1);
+       const char *ptr;
+       char *tmp;
+       char *ret = NULL;
+       int idx = 0;
+       int out_idx;
+       int out_sz;
+       enum {
+               STATE_START,
+               STATE_FIND,
+               STATE_CHECK,
+               STATE_END
+       } state;
+
+       if (!src || !pattern) {
+               return NULL;
+       }
+
+       out_sz = strlen(src);
+       ret = strdup(src);
        if (!ret) {
                ErrPrint("Heap: %s\n", strerror(errno));
                return NULL;
        }
 
-       pattern_idx = 0;
-       ret_idx = 0;
-       matched = 0;
-       for (src_idx = 0; src[src_idx]; src_idx++) {
-               if (!pattern[pattern_idx]) {
-                       while (replace[target_idx]) {
-                               ret[ret_idx] = replace[target_idx];
-                               ret_idx++;
-                               target_idx++;
-
-                               if (ret_idx >= bufsz) {
-                                       char *tmp;
-
-                                       tmp = extend_heap(ret, &bufsz, incsz);
+       out_idx = 0;
+       for (state = STATE_START, ptr = src; state != STATE_END; ptr++) {
+               switch (state) {
+               case STATE_START:
+                       if (*ptr == '\0') {
+                               state = STATE_END;
+                       } else if (!isblank(*ptr)) {
+                               state = STATE_FIND;
+                               ptr--;
+                       }
+                       break;
+               case STATE_FIND:
+                       if (*ptr == '\0') {
+                               state = STATE_END;
+                       } else if (*ptr == *pattern) {
+                               state = STATE_CHECK;
+                               ptr--;
+                               idx = 0;
+                       } else {
+                               ret[out_idx] = *ptr;
+                               out_idx++;
+                               if (out_idx == out_sz) {
+                                       tmp = extend_heap(ret, &out_sz, strlen(replace) + 1);
                                        if (!tmp) {
-                                               ErrPrint("Heap: %s\n", strerror(errno));
                                                DbgFree(ret);
                                                return NULL;
                                        }
                                        ret = tmp;
                                }
                        }
+                       break;
+               case STATE_CHECK:
+                       if (!pattern[idx]) {
+                               /*!
+                                * If there is no space for copying the replacement,
+                                * Extend size of the return buffer.
+                                */
+                               if (out_sz - out_idx < strlen(replace) + 1) {
+                                       tmp = extend_heap(ret, &out_sz, strlen(replace) + 1);
+                                       if (!tmp) {
+                                               DbgFree(ret);
+                                               return NULL;
+                                       }
+                                       ret = tmp;
+                               }
 
-                       pattern_idx = 0;
-                       src--;
-                       matched++;
-                       continue;
-               } else if (src[src_idx] == pattern[pattern_idx]) {
-                       if (pattern_idx == 0) {
-                               src_rollback_idx = src_idx;
-                               ret_rollback_idx = ret_idx;
-                               target_idx = 0;
-                       }
+                               strcpy(ret + out_idx, replace);
+                               out_idx += strlen(replace);
 
-                       if (replace[target_idx]) {
-                               ret[ret_idx] = replace[target_idx];
-                               ret_idx++;
-                               target_idx++;
-                               if (ret_idx >= bufsz) {
-                                       char *tmp;
+                               state = STATE_FIND;
+                               ptr--;
+                       } else if (*ptr != pattern[idx]) {
+                               ptr -= idx;
 
-                                       tmp = extend_heap(ret, &bufsz, incsz);
+                               /* Copy the first matched character */
+                               ret[out_idx] = *ptr;
+                               out_idx++;
+                               if (out_idx == out_sz) {
+                                       tmp = extend_heap(ret, &out_sz, strlen(replace) + 1);
                                        if (!tmp) {
-                                               ErrPrint("Heap: %s\n", strerror(errno));
                                                DbgFree(ret);
                                                return NULL;
                                        }
+
                                        ret = tmp;
                                }
-                       }
-
-                       pattern_idx++;
-                       continue;
-               } else if (pattern_idx > 0) {
-                       src_idx = src_rollback_idx;
-                       ret_idx = ret_rollback_idx;
-                       pattern_idx = 0;
-               }
-
-               ret[ret_idx] = src[src_idx];
-               ret_idx++;
-               if (ret_idx >= bufsz) {
-                       char *tmp;
 
-                       tmp = extend_heap(ret, &bufsz, incsz);
-                       if (!tmp) {
-                               ErrPrint("Heap: %s\n", strerror(errno));
-                               DbgFree(ret);
-                               return NULL;
+                               state = STATE_FIND;
+                       } else {
+                               idx++;
                        }
-                       ret = tmp;
+                       break;
+               default:
+                       break;
                }
        }
-       if (matched) {
-               ret[ret_idx] = '\0';
-       } else {
-               DbgFree(ret);
-               ret = NULL;
-       }
+
        return ret;
 }
 
@@ -326,91 +358,69 @@ HAPI const char *util_uri_to_path(const char *uri)
        int len;
 
        len = strlen(SCHEMA_FILE);
-       if (strncasecmp(uri, SCHEMA_FILE, len))
+       if (strncasecmp(uri, SCHEMA_FILE, len)) {
                return NULL;
+       }
 
        return uri + len;
 }
 
-static inline void compensate_timer(Ecore_Timer *timer)
+HAPI double util_time_delay_for_compensation(double period)
 {
+       unsigned long long curtime;
+       unsigned long long _period;
+       unsigned long long remain;
        struct timeval tv;
-       struct timeval compensator;
-       double delay;
-       double pending;
+       double ret;
 
-       if (ecore_timer_interval_get(timer) <= 1.0f) {
-               DbgPrint("Doesn't need to sync the timer to start from ZERO sec\n");
-               return;
+       if (period == 0.0f) {
+               DbgPrint("Period is ZERO\n");
+               return 0.0f;
        }
 
-       if (gettimeofday(&tv, NULL) < 0) {
-               ErrPrint("Error: %s\n", strerror(errno));
-               return;
+       if (gettimeofday(&tv, NULL) < 0){
+               ErrPrint("gettimeofday: %s\n", strerror(errno));
+               return period;
+       }
+
+       curtime = (unsigned long long)tv.tv_sec * 1000000llu + (unsigned long long)tv.tv_usec;
+
+       _period = (unsigned long long)(period * (double)1000000);
+       if (_period == 0llu) {
+               ErrPrint("%lf <> %llu\n", period, _period);
+               return period;
        }
 
-       compensator.tv_sec = tv.tv_sec % 60;
-       if (compensator.tv_sec == 0)
-               compensator.tv_sec = 59;
+       remain = curtime % _period;
 
-       delay = 60.0f - ((double)compensator.tv_sec + ((double)tv.tv_usec / 1000000.0f));
-       pending = ecore_timer_pending_get(timer);
-       ecore_timer_delay(timer, delay - pending);
-       DbgPrint("COMPENSATED: %lf\n", delay);
+       ret = (double)remain / (double)1000000;
+       return period - ret;
 }
 
 HAPI void *util_timer_add(double interval, Eina_Bool (*cb)(void *data), void *data)
 {
        Ecore_Timer *timer;
+       double delay;
 
        timer = ecore_timer_add(interval, cb, data);
-       if (!timer)
+       if (!timer) {
                return NULL;
+       }
+
+       delay = util_time_delay_for_compensation(interval) - interval;
+       ecore_timer_delay(timer, delay);
+       DbgPrint("Compensate timer: %lf\n", delay);
 
-       compensate_timer(timer);
        return timer;
 }
 
 HAPI void util_timer_interval_set(void *timer, double interval)
 {
+       double delay;
        ecore_timer_interval_set(timer, interval);
-       compensate_timer(timer);
-}
-
-HAPI char *util_get_file_kept_in_safe(const char *id)
-{
-       const char *path;
-       char *new_path;
-       int len;
-       int base_idx;
-
-       path = util_uri_to_path(id);
-       if (!path) {
-               ErrPrint("Invalid URI(%s)\n", id);
-               return NULL;
-       }
-
-       /*!
-        * TODO: Remove me
-        */
-       if (OVERWRITE_CONTENT)
-               return strdup(path);
-
-       len = strlen(path);
-       base_idx = len - 1;
 
-       while (base_idx > 0 && path[base_idx] != '/') base_idx--;
-       base_idx += (path[base_idx] == '/');
-
-       new_path = malloc(len + 10);
-       if (!new_path) {
-               ErrPrint("Heap: %s\n", strerror(errno));
-               return NULL;
-       }
-
-       strncpy(new_path, path, base_idx);
-       snprintf(new_path + base_idx, len + 10 - base_idx, "reader/%s", path + base_idx);
-       return new_path;
+       delay = util_time_delay_for_compensation(interval) - interval;
+       ecore_timer_delay(timer, delay);
 }
 
 HAPI int util_unlink_files(const char *folder)
@@ -423,26 +433,28 @@ HAPI int util_unlink_files(const char *folder)
 
        if (lstat(folder, &info) < 0) {
                ErrPrint("Error: %s\n", strerror(errno));
-               return -EIO;
+               return LB_STATUS_ERROR_IO;
        }
 
        if (!S_ISDIR(info.st_mode)) {
                ErrPrint("Error: %s is not a folder", folder);
-               return -EINVAL;
+               return LB_STATUS_ERROR_INVALID;
        }
 
        handle = opendir(folder);
        if (!handle) {
                ErrPrint("Error: %s\n", strerror(errno));
-               return -EIO;
+               return LB_STATUS_ERROR_IO;
        }
 
        while ((entry = readdir(handle))) {
-               if (!strcmp(entry->d_name, "."))
+               if (!strcmp(entry->d_name, ".")) {
                        continue;
+               }
 
-               if (!strcmp(entry->d_name, ".."))
+               if (!strcmp(entry->d_name, "..")) {
                        continue;
+               }
 
                len = strlen(folder) + strlen(entry->d_name) + 3;
                abspath = calloc(1, len);
@@ -452,14 +464,265 @@ HAPI int util_unlink_files(const char *folder)
                }
                snprintf(abspath, len - 1, "%s/%s", folder, entry->d_name);
 
-               if (unlink(abspath) < 0)
-                       DbgPrint("unlink: %s - %s\n", abspath, strerror(errno));
+               if (unlink(abspath) < 0) {
+                       DbgPrint("unlink: %s\n", strerror(errno));
+               }
+
+               DbgFree(abspath);
+       }
+
+       if (closedir(handle) < 0) {
+               ErrPrint("closedir: %s\n", strerror(errno));
+       }
+       return LB_STATUS_SUCCESS;
+}
+
+HAPI void util_remove_emergency_disk(void)
+{
+       int ret;
+       ret = umount(IMAGE_PATH);
+       if (ret < 0) {
+               ErrPrint("umount: %s\n", strerror(errno));
+       }
+
+       DbgPrint("Try to unmount[%s] %d\n", IMAGE_PATH, ret);
+       s_info.emergency_mounted = 0;
+}
+
+HAPI void util_prepare_emergency_disk(void)
+{
+       char *buf;
+       char *source = NULL;
+       char *type = NULL;
+       char *option = NULL;
+       char *ptr;
+       char *rollback_ptr;
+       int tag_idx;
+       int idx;
+       int len;
+       int ret;
+       static const char *tag[] = {
+               "source",
+               "type",
+               "option",
+               NULL,
+       };
+       enum tag_type {
+               TAG_SOURCE,
+               TAG_TYPE,
+               TAG_OPTION,
+               TAG_ERROR
+       };
+
+       buf = strdup(EMERGENCY_DISK);
+       if (!buf) {
+               ErrPrint("Failed to prepare emergency disk info\n");
+               return;
+       }
+
+       rollback_ptr = ptr = buf;
+       idx = 0;
+       tag_idx = 0;
+       len = strlen(ptr);
+
+       while (tag[tag_idx] != NULL && ptr != (buf + len)) {
+               if (tag[tag_idx][idx] == '\0') {
+                       if (*ptr == '=' || isblank(*ptr)) {
+                               switch (tag_idx) {
+                               case TAG_SOURCE:
+                                       if (source) {
+                                               ErrPrint("source[%s] is overrided\n", source);
+                                       }
+
+                                       while ((*ptr != '\0' && *ptr != ';') && (*ptr == '=' || isblank(*ptr))) {
+                                               ptr++;
+                                       }
+
+                                       source = ptr;
+                                       while (*ptr != '\0' && *ptr != ';') {
+                                               ptr++;
+                                       }
+
+                                       if (*source == '\0') {
+                                               type = NULL;
+                                       }
+
+                                       *ptr = '\0';
+                                       rollback_ptr = ptr + 1;
+                                       idx = 0;
+                                       break;
+                               case TAG_TYPE:
+                                       if (type) {
+                                               ErrPrint("type[%s] is overrided\n", type);
+                                       }
+
+                                       while ((*ptr != '\0' && *ptr != ';') && (*ptr == '=' || isblank(*ptr))) {
+                                               ptr++;
+                                       }
+
+                                       type = ptr;
+                                       while (*ptr != '\0' && *ptr != ';') {
+                                               ptr++;
+                                       }
+
+                                       if (*type == '\0') {
+                                               type = NULL;
+                                       }
+
+                                       *ptr = '\0';
+                                       rollback_ptr = ptr + 1;
+                                       idx = 0;
+                                       break;
+                               case TAG_OPTION:
+                                       if (option) {
+                                               ErrPrint("option[%s] is overrided\n", option);
+                                       }
+
+                                       while ((*ptr != '\0' && *ptr != ';') && (*ptr == '=' || isblank(*ptr))) {
+                                               ptr++;
+                                       }
+
+                                       option = ptr;
+                                       while (*ptr != '\0' && *ptr != ';') {
+                                               ptr++;
+                                       }
+
+                                       if (*option == '\0') {
+                                               option = NULL;
+                                       }
+
+                                       *ptr = '\0';
+                                       rollback_ptr = ptr + 1;
+                                       idx = 0;
+                                       break;
+                               default:
+                                       break;
+                               }
+                       } else {
+                               ptr = rollback_ptr;
+                               tag_idx++;
+                               idx = 0;
+                       }
+               } else if (tag[tag_idx][idx] != *ptr) {
+                       ptr = rollback_ptr;
+                       tag_idx++;
+                       idx = 0;
+               } else {
+                       ptr++;
+                       idx++;
+               } // tag
+       }
+
+       DbgPrint("source[%s] type[%s] option[%s]\n", source, type, option);
+
+       ret = mount(source, IMAGE_PATH, type, MS_NOSUID | MS_NOEXEC, option);
+       DbgFree(buf);
+       if (ret < 0) {
+               ErrPrint("Failed to mount: %s\n", strerror(errno));
+               return;
+       }
+
+       MINIMUM_SPACE = 0;
+
+       ErrPrint("Disk space is not enough, use the tmpfs. Currently required minimum space is %lu bytes\n", MINIMUM_SPACE);
+       if (chmod(IMAGE_PATH, 0750) < 0) {
+               ErrPrint("chmod: %s\n", strerror(errno));
+       }
+
+       if (chown(IMAGE_PATH, 5000, 5000) < 0) {
+               ErrPrint("chown: %s\n", strerror(errno));
+       }
 
-               free(abspath);
+       ret = smack_setlabel(IMAGE_PATH, DATA_SHARE_LABEL, SMACK_LABEL_ACCESS);
+       if (ret != 0) {
+               ErrPrint("Failed to set SMACK for %s (%d)\n", IMAGE_PATH, ret);
+       } else {
+               ret = smack_setlabel(IMAGE_PATH, "1", SMACK_LABEL_TRANSMUTE);
+               DbgPrint("[%s] is successfully created (t: %d)\n", IMAGE_PATH, ret);
        }
 
-       closedir(handle);
-       return 0;
+       if (mkdir(ALWAYS_PATH, 0755) < 0) {
+               ErrPrint("mkdir: (%s) %s\n", ALWAYS_PATH, strerror(errno));
+       } else {
+               if (chmod(ALWAYS_PATH, 0750) < 0) {
+                       ErrPrint("chmod: %s\n", strerror(errno));
+               }
+
+               if (chown(ALWAYS_PATH, 5000, 5000) < 0) {
+                       ErrPrint("chown: %s\n", strerror(errno));
+               }
+
+               ret = smack_setlabel(ALWAYS_PATH, DATA_SHARE_LABEL, SMACK_LABEL_ACCESS);
+               if (ret != 0) {
+                       ErrPrint("Failed to set SMACK for %s (%d)\n", ALWAYS_PATH, ret);
+               } else {
+                       ret = smack_setlabel(ALWAYS_PATH, "1", SMACK_LABEL_TRANSMUTE);
+                       DbgPrint("[%s] is successfully created (t: %d)\n", ALWAYS_PATH, ret);
+               }
+       }
+
+       if (mkdir(READER_PATH, 0755) < 0) {
+               ErrPrint("mkdir: (%s) %s\n", READER_PATH, strerror(errno));
+       } else {
+               if (chmod(READER_PATH, 0750) < 0) {
+                       ErrPrint("chmod: %s\n", strerror(errno));
+               }
+
+               if (chown(READER_PATH, 5000, 5000) < 0) {
+                       ErrPrint("chown: %s\n", strerror(errno));
+               }
+
+               ret = smack_setlabel(READER_PATH, DATA_SHARE_LABEL, SMACK_LABEL_ACCESS);
+               if (ret != 0) {
+                       ErrPrint("Failed to set SMACK for %s (%d)\n", READER_PATH, ret);
+               } else {
+                       ret = smack_setlabel(READER_PATH, "1", SMACK_LABEL_TRANSMUTE);
+                       DbgPrint("[%s] is successfully created (t: %d)\n", READER_PATH, ret);
+               }
+       }
+
+       s_info.emergency_mounted = 1;
+}
+
+HAPI int util_emergency_disk_is_mounted(void)
+{
+       return s_info.emergency_mounted;
+}
+
+HAPI void util_setup_log_disk(void)
+{
+       int ret;
+
+       if (access(SLAVE_LOG_PATH, R_OK | W_OK | X_OK) == 0) {
+               DbgPrint("[%s] is already accessible\n", SLAVE_LOG_PATH);
+               return;
+       }
+
+       DbgPrint("Initiate the critical log folder [%s]\n", SLAVE_LOG_PATH);
+       if (mkdir(SLAVE_LOG_PATH, 0755) < 0) {
+               ErrPrint("mkdir: %s\n", strerror(errno));
+       } else {
+               if (chmod(SLAVE_LOG_PATH, 0750) < 0) {
+                       ErrPrint("chmod: %s\n", strerror(errno));
+               }
+
+               if (chown(SLAVE_LOG_PATH, 5000, 5000) < 0) {
+                       ErrPrint("chown: %s\n", strerror(errno));
+               }
+
+               ret = smack_setlabel(SLAVE_LOG_PATH, DATA_SHARE_LABEL, SMACK_LABEL_ACCESS);
+               if (ret != 0) {
+                       ErrPrint("Failed to set SMACK for %s (%d)\n", SLAVE_LOG_PATH, ret);
+               } else {
+                       ret = smack_setlabel(SLAVE_LOG_PATH, "1", SMACK_LABEL_TRANSMUTE);
+                       DbgPrint("[%s] is successfully created (t: %d)\n", SLAVE_LOG_PATH, ret);
+               }
+       }
+}
+
+HAPI int util_service_is_enabled(const char *tag)
+{
+       return !!strcasestr(SERVICES, tag);
 }
 
 /* End of a file */