247602b7f2bd127208145f02feeb991038dd57da
[platform/core/appfw/ail.git] / tool / src / syncdb.c
1 /*
2  * ail
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  * Copyright (C) 2013-2014 Intel Corporation.
6  *
7  * Contact: Sabera Djelti <sabera.djelti@open.eurogiciel.org>,
8  * Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24
25
26 #include <string.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <dirent.h>
30 #include <unistd.h>
31 #include <sys/stat.h>
32 #include <errno.h>
33 #include <sys/smack.h>
34
35 #include "ail.h"
36 #include "ail_private.h"
37 #include "ail_db.h"
38
39
40 #ifdef _E
41 #undef _E
42 #endif
43 #define _E(fmt, arg...) fprintf(stderr, "[AIL_INITDB][E][%s,%d] "fmt"\n", __FUNCTION__, __LINE__, ##arg);
44
45 #ifdef _D
46 #undef _D
47 #endif
48 #define _D(fmt, arg...) fprintf(stderr, "[AIL_INITDB][D][%s,%d] "fmt"\n", __FUNCTION__, __LINE__, ##arg);
49
50 #define SET_DEFAULT_LABEL(x) \
51         if(smack_setlabel((x), "*", SMACK_LABEL_ACCESS)) _E("failed chsmack -a \"*\" %s", x) \
52         else _D("chsmack -a \"*\" %s", x)
53
54 static int syncdb_count_app(void)
55 {
56         ail_filter_h filter;
57         ail_error_e ret;
58         int total = 0;
59
60         ret = ail_filter_new(&filter);
61         if (ret != AIL_ERROR_OK) {
62                 return -1;
63         }
64
65         ret = ail_filter_add_bool(filter, AIL_PROP_NODISPLAY_BOOL, false);
66         if (ret != AIL_ERROR_OK) {
67                 ail_filter_destroy(filter);
68                 return -1;
69         }
70         ret = ail_filter_count_appinfo(filter, &total);
71         if (ret != AIL_ERROR_OK) {
72                 ail_filter_destroy(filter);
73                 return -1;
74         }
75
76         ail_filter_destroy(filter);
77
78         return total;
79 }
80
81
82
83 char* _desktop_to_package(const char* desktop)
84 {
85         char *package, *tmp;
86
87         retv_if(!desktop, NULL);
88
89         package = strdup(desktop);
90         retv_if(!package, NULL);
91
92         tmp = strrchr(package, '.');
93         if(tmp == NULL) {
94                 _E("[%s] is not a desktop file", package);
95                 free(package);
96                 return NULL;
97         }
98
99         if (strcmp(tmp, ".desktop")) {
100                 _E("%s is not a desktop file", desktop);
101                 free(package);
102                 return NULL;
103         }
104
105         *tmp = '\0';
106
107         return package;
108 }
109
110
111
112 int syncdb_load_directory(const char *directory)
113 {
114         DIR *dir;
115         struct dirent entry, *result;
116         int len, ret;
117         char buf[BUFSZE];
118         int total_cnt = 0;
119         int ok_cnt = 0;
120
121         // desktop file
122         dir = opendir(directory);
123         if (!dir) {
124                 if (strerror_r(errno, buf, sizeof(buf)) == 0)
125                         _E("Failed to access the [%s] because %s\n", directory, buf);
126                 return AIL_ERROR_FAIL;
127         }
128
129         len = strlen(directory) + 1;
130         _D("Loading desktop files from %s", directory);
131
132         for (ret = readdir_r(dir, &entry, &result);
133                         ret == 0 && result != NULL;
134                         ret = readdir_r(dir, &entry, &result)) {
135                 char *package;
136
137                 if (entry.d_name[0] == '.') continue;
138                 total_cnt++;
139                 package = _desktop_to_package(entry.d_name);
140                 if (!package) {
141                         _E("Failed to convert file to package[%s]", entry.d_name);
142                         continue;
143                 }
144
145                 if (ail_desktop_add(package) != AIL_ERROR_OK) {
146                         _E("Failed to add a package[%s]", package);
147                 } else {
148                         ok_cnt++;
149                 }
150                 free(package);
151         }
152
153         _D("Application-Desktop process : Success [%d], fail[%d], total[%d] \n", ok_cnt, total_cnt-ok_cnt, total_cnt);
154         closedir(dir);
155
156         return AIL_ERROR_OK;
157 }
158
159
160
161 static int syncdb_change_perm(const char *db_file)
162 {
163         char buf[BUFSZE];
164         char journal_file[BUFSZE];
165         char *files[3];
166         int ret, i;
167
168         files[0] = (char *)db_file;
169         files[1] = journal_file;
170         files[2] = NULL;
171
172         retv_if(!db_file, AIL_ERROR_FAIL);
173
174         snprintf(journal_file, sizeof(journal_file), "%s%s", db_file, "-journal");
175
176         for (i = 0; files[i]; i++) {
177                 ret = chown(files[i], GLOBAL_USER, OWNER_ROOT);
178                 if (ret == -1) {
179                         strerror_r(errno, buf, sizeof(buf));
180                         _E("FAIL : chown %s %d.%d, because %s", db_file, OWNER_ROOT, OWNER_ROOT, buf);
181                         return AIL_ERROR_FAIL;
182                 }
183
184                 ret = chmod(files[i], S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
185                 if (ret == -1) {
186                         strerror_r(errno, buf, sizeof(buf));
187                         _E("FAIL : chmod %s 0664, because %s", db_file, buf);
188                         return AIL_ERROR_FAIL;
189                 }
190         }
191
192         return AIL_ERROR_OK;
193 }
194
195
196 static int __is_authorized()
197 {
198         /* ail_init db should be called by as root privilege. */
199
200         uid_t uid = getuid();
201         uid_t euid = geteuid();
202         //euid need to be root to allow smack label changes during initialization
203         if ((uid_t) OWNER_ROOT == uid)
204                 return 1;
205         else
206                 return 0;
207 }
208
209 int xsystem(const char *argv[])
210 {
211         int status = 0;
212         pid_t pid;
213         pid = fork();
214         switch (pid) {
215         case -1:
216                 perror("fork failed");
217                 return -1;
218         case 0:
219                 /* child */
220                 execvp(argv[0], (char *const *)argv);
221                 _exit(-1);
222         default:
223                 /* parent */
224                 break;
225         }
226         if (waitpid(pid, &status, 0) == -1) {
227                 perror("waitpid failed");
228                 return -1;
229         }
230         if (WIFSIGNALED(status)) {
231                 perror("signal");
232                 return -1;
233         }
234         if (!WIFEXITED(status)) {
235                 /* shouldn't happen */
236                 perror("should not happen");
237                 return -1;
238         }
239         return WEXITSTATUS(status);
240 }
241
242 int main(int argc, char *argv[])
243 {
244         int ret;
245
246         if (!__is_authorized()) {
247                 fprintf(stderr, "You are not an authorized user!\n");
248                 _D("You are not root user!\n");
249                 return -1;
250         }
251         if (access(APP_INFO_DB_FILE, F_OK)) {
252                 fprintf(stderr, "Application database %s is missing, please use ail_createdb to create one before\n", APP_INFO_DB_FILE);
253                 return AIL_ERROR_FAIL;
254         }
255         ret = setenv("AIL_INITDB", "1", 1);
256         _D("AIL_INITDB : %d", ret);
257         setresuid(GLOBAL_USER, GLOBAL_USER, OWNER_ROOT);
258
259         if (db_open(DB_OPEN_RW, GLOBAL_USER) != AIL_ERROR_OK) {
260                 _E("Fail to create system databases");
261                 return AIL_ERROR_DB_FAILED;
262         }
263         ret = syncdb_load_directory(USR_DESKTOP_DIRECTORY);
264         if (ret == AIL_ERROR_FAIL) {
265                 _E("cannot load usr desktop directory.");
266         }
267
268         return AIL_ERROR_OK;
269 }
270
271
272
273 // END