2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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.
26 #include <sys/types.h>
29 #include <sys/statvfs.h>
30 #include <sys/mount.h>
32 #include <sys/smack.h>
36 #if defined(HAVE_LIVEBOX)
37 #include <dynamicbox_errno.h>
38 #include <dynamicbox_conf.h>
40 #include "lite-errno.h"
41 #define DYNAMICBOX_CONF_IMAGE_PATH "/tmp/"
49 int emergency_mounted;
51 .emergency_mounted = 0,
56 HAPI unsigned long util_string_hash(const char *str)
58 unsigned long ret = 0;
61 ret += (unsigned long)(*str++);
68 HAPI double util_timestamp(void)
70 #if defined(_USE_ECORE_TIME_GET)
71 return ecore_time_get();
74 if (gettimeofday(&tv, NULL) < 0) {
75 static unsigned long internal_count = 0;
76 ErrPrint("failed to get time of day: %s\n", strerror(errno));
77 tv.tv_sec = internal_count++;
81 return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
85 HAPI int util_check_ext(const char *filename, const char *check_ptr)
89 name_len = strlen(filename);
90 while (--name_len >= 0 && *check_ptr) {
91 if (filename[name_len] != *check_ptr) {
92 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
98 return DBOX_STATUS_ERROR_NONE;
101 HAPI int util_unlink(const char *filename)
108 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
111 desclen = strlen(filename) + 6; /* .desc */
112 descfile = malloc(desclen);
114 ErrPrint("Heap: %s\n", strerror(errno));
115 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
118 ret = snprintf(descfile, desclen, "%s.desc", filename);
120 ErrPrint("Error: %s\n", strerror(errno));
122 return DBOX_STATUS_ERROR_FAULT;
125 (void)unlink(descfile);
127 (void)unlink(filename);
129 return DBOX_STATUS_ERROR_NONE;
132 HAPI char *util_slavename(void)
134 char slavename[BUFSIZ];
135 static unsigned long idx = 0;
137 snprintf(slavename, sizeof(slavename), "%lu_%lf", idx++, util_timestamp());
138 return strdup(slavename);
141 HAPI const char *util_basename(const char *name)
144 length = name ? strlen(name) : 0;
149 while (--length > 0 && name[length] != '/');
151 return length <= 0 ? name : (name + length + (name[length] == '/'));
155 * Return size of stroage in Bytes unit.
157 HAPI unsigned long long util_free_space(const char *path)
160 unsigned long long space;
162 if (statvfs(path, &st) < 0) {
163 ErrPrint("statvfs: %s\n", strerror(errno));
167 space = (unsigned long long)st.f_bsize * (unsigned long long)st.f_bavail;
168 DbgPrint("Available size: %llu, f_bsize: %lu, f_bavail: %lu\n", space, st.f_bsize, st.f_bavail);
171 * Must have to check the overflow
177 static inline char *extend_heap(char *buffer, int *sz, int incsz)
182 tmp = realloc(buffer, *sz);
184 ErrPrint("Heap: %s\n", strerror(errno));
191 HAPI char *util_replace_string(const char *src, const char *pattern, const char *replace)
206 if (!src || !pattern) {
210 out_sz = strlen(src);
213 ErrPrint("Heap: %s\n", strerror(errno));
218 for (state = STATE_START, ptr = src; state != STATE_END; ptr++) {
223 } else if (!isblank(*ptr)) {
231 } else if (*ptr == *pattern) {
238 if (out_idx == out_sz) {
239 tmp = extend_heap(ret, &out_sz, strlen(replace) + 1);
251 * If there is no space for copying the replacement,
252 * Extend size of the return buffer.
254 if (out_sz - out_idx < strlen(replace) + 1) {
255 tmp = extend_heap(ret, &out_sz, strlen(replace) + 1);
263 strcpy(ret + out_idx, replace);
264 out_idx += strlen(replace);
268 } else if (*ptr != pattern[idx]) {
271 /* Copy the first matched character */
274 if (out_idx == out_sz) {
275 tmp = extend_heap(ret, &out_sz, strlen(replace) + 1);
297 HAPI const char *util_uri_to_path(const char *uri)
301 len = strlen(SCHEMA_FILE);
302 if (strncasecmp(uri, SCHEMA_FILE, len)) {
309 HAPI double util_time_delay_for_compensation(double period)
311 unsigned long long curtime;
312 unsigned long long _period;
313 unsigned long long remain;
317 if (period == 0.0f) {
318 DbgPrint("Period is ZERO\n");
322 if (gettimeofday(&tv, NULL) < 0){
323 ErrPrint("gettimeofday: %s\n", strerror(errno));
327 curtime = (unsigned long long)tv.tv_sec * 1000000llu + (unsigned long long)tv.tv_usec;
329 _period = (unsigned long long)(period * (double)1000000);
330 if (_period == 0llu) {
331 ErrPrint("%lf <> %llu\n", period, _period);
335 remain = curtime % _period;
337 ret = (double)remain / (double)1000000;
341 HAPI void *util_timer_add(double interval, Eina_Bool (*cb)(void *data), void *data)
346 timer = ecore_timer_add(interval, cb, data);
351 delay = util_time_delay_for_compensation(interval) - interval;
352 ecore_timer_delay(timer, delay);
353 DbgPrint("Compensate timer: %lf\n", delay);
358 HAPI void util_timer_interval_set(void *timer, double interval)
361 ecore_timer_interval_set(timer, interval);
363 delay = util_time_delay_for_compensation(interval) - interval;
364 ecore_timer_delay(timer, delay);
367 HAPI int util_unlink_files(const char *folder)
371 struct dirent *entry;
375 if (lstat(folder, &info) < 0) {
376 ErrPrint("Error: %s\n", strerror(errno));
377 return DBOX_STATUS_ERROR_IO_ERROR;
380 if (!S_ISDIR(info.st_mode)) {
381 ErrPrint("Error: %s is not a folder", folder);
382 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
385 handle = opendir(folder);
387 ErrPrint("Error: %s\n", strerror(errno));
388 return DBOX_STATUS_ERROR_IO_ERROR;
391 while ((entry = readdir(handle))) {
392 if (!strcmp(entry->d_name, ".")) {
396 if (!strcmp(entry->d_name, "..")) {
400 len = strlen(folder) + strlen(entry->d_name) + 3;
401 abspath = calloc(1, len);
403 ErrPrint("Heap: %s\n", strerror(errno));
406 snprintf(abspath, len - 1, "%s/%s", folder, entry->d_name);
408 if (unlink(abspath) < 0) {
409 DbgPrint("unlink: %s\n", strerror(errno));
415 if (closedir(handle) < 0) {
416 ErrPrint("closedir: %s\n", strerror(errno));
418 return DBOX_STATUS_ERROR_NONE;
421 HAPI void util_remove_emergency_disk(void)
424 ret = umount(DYNAMICBOX_CONF_IMAGE_PATH);
426 ErrPrint("umount: %s\n", strerror(errno));
429 DbgPrint("Try to unmount[%s] %d\n", DYNAMICBOX_CONF_IMAGE_PATH, ret);
430 s_info.emergency_mounted = 0;
433 HAPI void util_prepare_emergency_disk(void)
445 static const char *tag[] = {
458 buf = strdup(DYNAMICBOX_CONF_EMERGENCY_DISK);
460 ErrPrint("Failed to prepare emergency disk info\n");
464 rollback_ptr = ptr = buf;
469 while (tag[tag_idx] != NULL && ptr != (buf + len)) {
470 if (tag[tag_idx][idx] == '\0') {
471 if (*ptr == '=' || isblank(*ptr)) {
475 ErrPrint("source[%s] is overrided\n", source);
478 while ((*ptr != '\0' && *ptr != ';') && (*ptr == '=' || isblank(*ptr))) {
483 while (*ptr != '\0' && *ptr != ';') {
487 if (*source == '\0') {
492 rollback_ptr = ptr + 1;
497 ErrPrint("type[%s] is overrided\n", type);
500 while ((*ptr != '\0' && *ptr != ';') && (*ptr == '=' || isblank(*ptr))) {
505 while (*ptr != '\0' && *ptr != ';') {
514 rollback_ptr = ptr + 1;
519 ErrPrint("option[%s] is overrided\n", option);
522 while ((*ptr != '\0' && *ptr != ';') && (*ptr == '=' || isblank(*ptr))) {
527 while (*ptr != '\0' && *ptr != ';') {
531 if (*option == '\0') {
536 rollback_ptr = ptr + 1;
547 } else if (tag[tag_idx][idx] != *ptr) {
557 DbgPrint("source[%s] type[%s] option[%s]\n", source, type, option);
559 ret = mount(source, DYNAMICBOX_CONF_IMAGE_PATH, type, MS_NOSUID | MS_NOEXEC, option);
562 ErrPrint("Failed to mount: %s\n", strerror(errno));
566 ErrPrint("Disk space is not enough, use the tmpfs. Currently required minimum space is %lu bytes\n", DYNAMICBOX_CONF_MINIMUM_SPACE);
567 if (chmod(DYNAMICBOX_CONF_IMAGE_PATH, 0750) < 0) {
568 ErrPrint("chmod: %s\n", strerror(errno));
571 if (chown(DYNAMICBOX_CONF_IMAGE_PATH, 5000, 5000) < 0) {
572 ErrPrint("chown: %s\n", strerror(errno));
575 ret = smack_setlabel(DYNAMICBOX_CONF_IMAGE_PATH, DATA_SHARE_LABEL, SMACK_LABEL_ACCESS);
577 ErrPrint("Failed to set SMACK for %s (%d)\n", DYNAMICBOX_CONF_IMAGE_PATH, ret);
579 ret = smack_setlabel(DYNAMICBOX_CONF_IMAGE_PATH, "1", SMACK_LABEL_TRANSMUTE);
580 DbgPrint("[%s] is successfully created (t: %d)\n", DYNAMICBOX_CONF_IMAGE_PATH, ret);
583 if (mkdir(DYNAMICBOX_CONF_ALWAYS_PATH, 0755) < 0) {
584 ErrPrint("mkdir: (%s) %s\n", DYNAMICBOX_CONF_ALWAYS_PATH, strerror(errno));
586 if (chmod(DYNAMICBOX_CONF_ALWAYS_PATH, 0750) < 0) {
587 ErrPrint("chmod: %s\n", strerror(errno));
590 if (chown(DYNAMICBOX_CONF_ALWAYS_PATH, 5000, 5000) < 0) {
591 ErrPrint("chown: %s\n", strerror(errno));
594 ret = smack_setlabel(DYNAMICBOX_CONF_ALWAYS_PATH, DATA_SHARE_LABEL, SMACK_LABEL_ACCESS);
596 ErrPrint("Failed to set SMACK for %s (%d)\n", DYNAMICBOX_CONF_ALWAYS_PATH, ret);
598 ret = smack_setlabel(DYNAMICBOX_CONF_ALWAYS_PATH, "1", SMACK_LABEL_TRANSMUTE);
599 DbgPrint("[%s] is successfully created (t: %d)\n", DYNAMICBOX_CONF_ALWAYS_PATH, ret);
603 if (mkdir(DYNAMICBOX_CONF_READER_PATH, 0755) < 0) {
604 ErrPrint("mkdir: (%s) %s\n", DYNAMICBOX_CONF_READER_PATH, strerror(errno));
606 if (chmod(DYNAMICBOX_CONF_READER_PATH, 0750) < 0) {
607 ErrPrint("chmod: %s\n", strerror(errno));
610 if (chown(DYNAMICBOX_CONF_READER_PATH, 5000, 5000) < 0) {
611 ErrPrint("chown: %s\n", strerror(errno));
614 ret = smack_setlabel(DYNAMICBOX_CONF_READER_PATH, DATA_SHARE_LABEL, SMACK_LABEL_ACCESS);
616 ErrPrint("Failed to set SMACK for %s (%d)\n", DYNAMICBOX_CONF_READER_PATH, ret);
618 ret = smack_setlabel(DYNAMICBOX_CONF_READER_PATH, "1", SMACK_LABEL_TRANSMUTE);
619 DbgPrint("[%s] is successfully created (t: %d)\n", DYNAMICBOX_CONF_READER_PATH, ret);
623 s_info.emergency_mounted = 1;
626 HAPI int util_emergency_disk_is_mounted(void)
628 return s_info.emergency_mounted;
631 HAPI void util_setup_log_disk(void)
635 if (access(DYNAMICBOX_CONF_LOG_PATH, R_OK | W_OK | X_OK) == 0) {
636 DbgPrint("[%s] is already accessible\n", DYNAMICBOX_CONF_LOG_PATH);
640 DbgPrint("Initiate the critical log folder [%s]\n", DYNAMICBOX_CONF_LOG_PATH);
641 if (mkdir(DYNAMICBOX_CONF_LOG_PATH, 0755) < 0) {
642 ErrPrint("mkdir: %s\n", strerror(errno));
644 if (chmod(DYNAMICBOX_CONF_LOG_PATH, 0750) < 0) {
645 ErrPrint("chmod: %s\n", strerror(errno));
648 if (chown(DYNAMICBOX_CONF_LOG_PATH, 5000, 5000) < 0) {
649 ErrPrint("chown: %s\n", strerror(errno));
652 ret = smack_setlabel(DYNAMICBOX_CONF_LOG_PATH, DATA_SHARE_LABEL, SMACK_LABEL_ACCESS);
654 ErrPrint("Failed to set SMACK for %s (%d)\n", DYNAMICBOX_CONF_LOG_PATH, ret);
656 ret = smack_setlabel(DYNAMICBOX_CONF_LOG_PATH, "1", SMACK_LABEL_TRANSMUTE);
657 DbgPrint("[%s] is successfully created (t: %d)\n", DYNAMICBOX_CONF_LOG_PATH, ret);
662 HAPI int util_service_is_enabled(const char *tag)
664 return !!strcasestr(DYNAMICBOX_CONF_SERVICES, tag);