apply FSL(Flora Software License)
[framework/system/system-server.git] / ss_timemgr.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (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
7  *
8  *      http://www.tizenopensource.org/license
9  *
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.
15 */
16
17
18 #include <stdio.h>
19 #include <stdbool.h>
20 #include <unistd.h>
21 #include <sys/types.h>
22 #include <errno.h>
23 #include <sys/stat.h>
24 #include <pmapi.h>
25 #include <vconf.h>
26
27 #include <sysman.h>
28 #include "include/ss_data.h"
29 #include "ss_queue.h"
30 #include "ss_log.h"
31
32 #include <time.h>
33 #include <sys/ioctl.h>
34 #include <linux/rtc.h>
35 #include <fcntl.h>
36
37 #include <ITapiMisc.h>
38
39 static const char default_rtc0[] = "/dev/rtc0";
40 static const char default_rtc1[] = "/dev/rtc1";
41 static const char default_localtime[] = "/opt/etc/localtime";
42
43 char *substring(const char *str, size_t begin, size_t len)
44 {
45         if (str == 0 || strlen(str) == 0 || strlen(str) < begin
46             || strlen(str) < (begin + len))
47                 return 0;
48
49         return strndup(str + begin, len);
50 }
51
52 int handle_timezone(char *str)
53 {
54         int ret;
55         struct stat sts;
56         const char *sympath = default_localtime;
57
58         if (str == NULL)
59                 return -1;
60         const char *tzpath = str;
61
62         PRT_TRACE("TZPATH = %s\n", tzpath);
63
64         /* unlink current link
65          * eg. rm /opt/etc/localtime */
66         if (stat(sympath, &sts) == -1 && errno == ENOENT) {
67                 /* DO NOTHING */
68         } else {
69                 ret = unlink(sympath);
70                 if (ret < 0) {
71                         PRT_TRACE("unlink error : [%d]%s\n", ret,
72                                   strerror(errno));
73                         return -1;
74                 } else
75                         PRT_TRACE("unlink success\n");
76
77         }
78
79         /* symlink new link
80          * eg. ln -s /usr/share/zoneinfo/Asia/Seoul /opt/etc/localtime */
81         ret = symlink(tzpath, sympath);
82         if (ret < 0) {
83                 PRT_TRACE("symlink error : [%d]%s\n", ret, strerror(errno));
84                 return -1;
85         } else
86                 PRT_TRACE("symlink success\n");
87
88         tzset();
89         return 0;
90 }
91
92 /*
93  * TODO : error handling code should be added here.
94  */
95 int handle_date(char *str)
96 {
97         long int tmp = 0;
98         time_t timet = 0;
99         time_t before = 0;
100
101         if (str == NULL)
102                 return -1;
103
104         tmp = (long int)atoi(str);
105         timet = (time_t) tmp;
106
107         PRT_TRACE("ctime = %s", ctime(&timet));
108         vconf_set_int(VCONFKEY_SYSTEM_TIMECHANGE, timet);
109
110         return 0;
111 }
112
113 int set_datetime_action(int argc, char **argv)
114 {
115         int ret = 0;
116         unsigned int pm_state;
117         if (argc < 1)
118                 return -1;
119         if (vconf_get_int(VCONFKEY_PM_STATE, &ret) != 0)
120                 PRT_TRACE("Fail to get vconf value for pm state\n");
121         if (ret == 1)
122                 pm_state = 0x1;
123         else if (ret == 2)
124                 pm_state = 0x2;
125         else
126                 pm_state = 0x4;
127
128         pm_lock_state(pm_state, STAY_CUR_STATE, 0);
129         ret = handle_date(argv[0]);
130         pm_unlock_state(pm_state, STAY_CUR_STATE);
131         return ret;
132 }
133
134 int set_timezone_action(int argc, char **argv)
135 {
136         int ret;
137         unsigned int pm_state;
138         if (argc < 1)
139                 return -1;
140         if (vconf_get_int(VCONFKEY_PM_STATE, &ret) != 0)
141                 PRT_TRACE("Fail to get vconf value for pm state\n");
142         if (ret == 1)
143                 pm_state = 0x1;
144         else if (ret == 2)
145                 pm_state = 0x2;
146         else
147                 pm_state = 0x4;
148
149         pm_lock_state(pm_state, STAY_CUR_STATE, 0);
150         ret = handle_timezone(argv[0]);
151         pm_unlock_state(pm_state, STAY_CUR_STATE);
152         return ret;
153 }
154
155 int ss_time_manager_init(void)
156 {
157         ss_action_entry_add_internal(PREDEF_SET_DATETIME, set_datetime_action,
158                                      NULL, NULL);
159         ss_action_entry_add_internal(PREDEF_SET_TIMEZONE, set_timezone_action,
160                                      NULL, NULL);
161         return 0;
162 }