tizen 2.4 release
[framework/appfw/aul-1.git] / src / aul_path.c
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
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 #define _GNU_SOURCE
19 #include <unistd.h>
20 #include <linux/limits.h>
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26
27 #include <pkgmgr-info.h>
28 #include <pkgmgrinfo_zone.h>
29
30 #include "aul_api.h"
31 #include "aul_util.h"
32 #include "simple_util.h"
33 #include "aul.h"
34 #include "aul_zone.h"
35
36 #define _MAX_PACKAGE_ID_LEN 256
37 #define _MAX_BASE_PATH_LEN 512
38
39 static const char _EXTERNAL_APP_SPECIFIC_PATH[] = "/opt/storage/sdcard/apps/";
40 static const char _APP_SPECIFIC_PATH[] = "/opt/usr/apps/";
41 static const char _PRELOADED_APP_SPECIFIC_PATH[] = "/usr/apps/";
42
43 static const char _DATA_DIR[] = "data/";
44 static const char _CACHE_DIR[] = "cache/";
45 static const char _RESOURCE_DIR[] = "res/";
46 static const char _TEP_RESOURCE_DIR[] = "res/tep/";
47 static const char _SHARED_DATA_DIR[] = "shared/data/";
48 static const char _SHARED_TRUSTED_DIR[] = "shared/trusted/";
49 static const char _SHARED_RESOURCE_DIR[] = "shared/res/";
50
51 static char external_root_path[_MAX_BASE_PATH_LEN] = {0,};
52 static char root_path[_MAX_BASE_PATH_LEN] = {0,};
53 static char data_path[_MAX_BASE_PATH_LEN] = {0,};
54 static char cache_path[_MAX_BASE_PATH_LEN] = {0,};
55 static char resource_path[_MAX_BASE_PATH_LEN] = {0,};
56 static char tep_resource_path[_MAX_BASE_PATH_LEN] = {0,};
57 static char shared_data_path[_MAX_BASE_PATH_LEN] = {0,};
58 static char shared_resource_path[_MAX_BASE_PATH_LEN] = {0,};
59 static char shared_trusted_path[_MAX_BASE_PATH_LEN] = {0,};
60 static char external_data_path[_MAX_BASE_PATH_LEN] = {0,};
61 static char external_cache_path[_MAX_BASE_PATH_LEN] = {0,};
62 static char external_shared_data_path[_MAX_BASE_PATH_LEN] = {0,};
63 static char pkgid[_MAX_PACKAGE_ID_LEN] = {0,};
64
65 static int __get_pkgid_by_appid(char *pkgid, int pkgid_len, const char *appid)
66 {
67         pkgmgrinfo_appinfo_h handle = NULL;
68         char *tmp_pkgid = NULL;
69
70         // get pkginfo handle
71         int err = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
72         if (err != PMINFO_R_OK) {
73                 _E("Failed to get app info. (err:%d)", err);
74                 return AUL_R_ENOAPP;
75         }
76
77         // get and set pkgid
78         err = pkgmgrinfo_appinfo_get_pkgid(handle, &tmp_pkgid);
79         if (err != PMINFO_R_OK) {
80                 _E("Failed to get pkgid. (err:%d)", err);
81                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
82                 return AUL_R_ENOAPP;
83         }
84         strncpy(pkgid, tmp_pkgid, pkgid_len);
85         pkgmgrinfo_appinfo_destroy_appinfo(handle);
86
87         return AUL_R_OK;
88 }
89
90 static int __get_pkgid(char* pkgid, int pkgid_len)
91 {
92         char appid[_MAX_PACKAGE_ID_LEN] = {0,};
93         const char *preinit_pkgid = NULL;
94
95         preinit_pkgid = aul_get_preinit_pkgid();
96         if (preinit_pkgid != NULL) {
97                 strncpy(pkgid, preinit_pkgid, pkgid_len);
98                 return AUL_R_OK;
99         }
100
101         // get appid
102         int err = aul_app_get_appid_bypid(getpid(), appid, _MAX_PACKAGE_ID_LEN - 1);
103         if (err != AUL_R_OK) {
104                 _E("Failed to get appid. (err:%d)", err);
105                 return err;
106         }
107
108         return __get_pkgid_by_appid(pkgid, pkgid_len, appid);
109 }
110
111 static const char* __get_app_specific_path(const char *pkgid)
112 {
113         pkgmgrinfo_pkginfo_h handle;
114         int ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
115         if (ret != PMINFO_R_OK)
116                 return NULL;
117
118         bool preload;
119         ret = pkgmgrinfo_pkginfo_is_preload(handle, &preload);
120         if (ret != PMINFO_R_OK) {
121                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
122                 return NULL;
123         }
124
125         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
126
127         if (preload) {
128                 return _PRELOADED_APP_SPECIFIC_PATH;
129         }
130
131         return _APP_SPECIFIC_PATH;
132 }
133
134 static int __get_root_path(char *root_path, int root_path_len, bool external,
135                            bool can_write)
136 {
137         char pkgid[_MAX_PACKAGE_ID_LEN] = {0,};
138         const char *specific_path = NULL;
139
140         int err = __get_pkgid(pkgid, _MAX_PACKAGE_ID_LEN - 1);
141         if (err != AUL_R_OK) {
142                 return err;
143         }
144
145         if (can_write)
146                 specific_path = external ? _EXTERNAL_APP_SPECIFIC_PATH : _APP_SPECIFIC_PATH;
147         else {
148                 specific_path = external ? _EXTERNAL_APP_SPECIFIC_PATH : __get_app_specific_path(pkgid);
149                 if (specific_path == NULL) {
150                         _E("out of memory");
151                         return AUL_R_ERROR;
152                 }
153         }
154
155         int specific_path_len = strlen(specific_path);
156         int pkgid_len = strlen(pkgid);
157         int total_len = specific_path_len + pkgid_len + 1;
158
159         if (total_len > root_path_len) {
160                 _E("Assert: path length %d is too long", total_len);
161                 assert(false);
162         }
163
164         strncat(root_path, specific_path, specific_path_len);
165         strncat(root_path + specific_path_len, pkgid, pkgid_len);
166         root_path[specific_path_len + pkgid_len] = '/';
167         root_path[specific_path_len + pkgid_len + 1] = '\0';
168
169         return AUL_R_OK;
170 }
171
172 static char* __get_base_path(bool can_write)
173 {
174         static char base_path[_MAX_BASE_PATH_LEN] = {0,};
175
176         base_path[0] = '\0';
177         if (__get_root_path(base_path, _MAX_BASE_PATH_LEN - 1, false,
178                             can_write) != AUL_R_OK)
179                 return NULL;
180
181         return base_path;
182 }
183
184 static int __get_path(char *path, int path_len, const char *dir_name,
185                       bool external, bool can_write)
186 {
187         char* root_path = NULL;
188         pkgmgrinfo_pkginfo_h pkginfo = NULL;
189         int is_res = 0;
190
191         if (dir_name == NULL)
192         {
193                 _E("Assert: dir name is NULL!");
194                 assert(false);
195         }
196         else if (strncmp(dir_name, _RESOURCE_DIR, strlen(_RESOURCE_DIR)) == 0 ||
197                         strncmp(dir_name, _SHARED_RESOURCE_DIR, strlen(_SHARED_RESOURCE_DIR)) == 0)
198         {
199                 char pkgid[_MAX_PACKAGE_ID_LEN] = {0,};
200                 if (__get_pkgid(pkgid, _MAX_PACKAGE_ID_LEN - 1) != AUL_R_OK)
201                 {
202                         _E("Assert: failed to get the package id!");
203                         assert(false);
204                 }
205
206                 if (pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkginfo) != PMINFO_R_OK)
207                 {
208                         _E("Failed to get the package info from pkgid!");
209                         return AUL_R_ERROR;
210                 }
211
212                 if (pkgmgrinfo_pkginfo_get_root_path(pkginfo, &root_path) != PMINFO_R_OK)
213                 {
214                         _E("Failed to get the root path from pkginfo!");
215                         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
216                         return AUL_R_ERROR;
217                 }
218
219                 is_res = 1;
220         }
221         else
222         {
223                 root_path = (char *) (external ? aul_get_app_external_root_path() :
224                         __get_base_path(can_write));
225                 if (root_path == NULL)
226                 {
227                         _E("root_path is NULL!");
228                         return AUL_R_ERROR;
229                 }
230         }
231
232         int dir_name_len = strlen(dir_name);
233         int root_path_len = strlen(root_path);
234         int total_len = root_path_len + dir_name_len;
235
236         if (total_len > path_len)
237         {
238                 _E("Assert: path length %d is too long", total_len);
239                 assert(false);
240         }
241
242         strncpy(path, root_path, root_path_len);
243         if (is_res)
244         {
245                 strncat(path, "/", 1);
246                 ++root_path_len;
247         }
248         strncpy(path + root_path_len, dir_name, dir_name_len);
249
250         if (pkginfo != NULL)
251         {
252                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
253         }
254
255         return AUL_R_OK;
256 }
257
258 static int __get_path_by_appid(char **path, const char *appid,
259                                const char *dir_name, bool external)
260 {
261         if (dir_name == NULL) {
262                 _E("Assert: dir name is NULL!");
263                 assert(false);
264         }
265
266         if (path == NULL || appid == NULL) {
267                 return AUL_R_EINVAL;
268         }
269
270         pkgmgrinfo_pkginfo_h pkginfo = NULL;
271         char *specific_path = NULL;
272         int total_len = 0;
273
274         char pkgid[_MAX_PACKAGE_ID_LEN] = {0,};
275         int err = __get_pkgid_by_appid(pkgid, _MAX_PACKAGE_ID_LEN - 1, appid);
276         if (err != AUL_R_OK) {
277                 return err;
278         }
279
280         if (strncmp(dir_name, _RESOURCE_DIR, strlen(_RESOURCE_DIR)) == 0 ||
281                 strncmp(dir_name, _SHARED_RESOURCE_DIR, strlen(_SHARED_RESOURCE_DIR)) == 0) {
282                 if (pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkginfo) != PMINFO_R_OK) {
283                         _E("Failed to get the package info from pkgid!");
284                         return AUL_R_ERROR;
285                 }
286
287                 if (pkgmgrinfo_pkginfo_get_root_path(pkginfo, &specific_path) != PMINFO_R_OK) {
288                         _E("Failed to get the root path from pkginfo!");
289                         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
290                         return AUL_R_ERROR;
291                 }
292
293                 total_len = strlen(specific_path) + strlen(dir_name) + 1;
294
295         } else {
296                 specific_path = (char *) (external ? _EXTERNAL_APP_SPECIFIC_PATH : _APP_SPECIFIC_PATH);
297                 total_len = strlen(specific_path) + strlen(pkgid) + 1 + strlen(dir_name);
298         }
299
300         if (total_len > _MAX_BASE_PATH_LEN - 1) {
301                 _E("Assert: path length %d is too long", total_len);
302                 assert(false);
303         }
304
305         *path = (char *)calloc(total_len + 1, sizeof(char));
306         if (*path == NULL) {
307                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
308                 return AUL_R_ERROR;
309         }
310
311         if (pkginfo != NULL) {
312                 snprintf(*path, total_len + 1, "%s/%s", specific_path, dir_name);
313                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
314         } else {
315                 snprintf(*path, total_len + 1, "%s%s/%s", specific_path, pkgid, dir_name);
316         }
317
318         return AUL_R_OK;
319 }
320
321 void _clear_path_cache(void)
322 {
323         external_root_path[0] = '\0';
324         root_path[0] = '\0';
325         data_path[0] = '\0';
326         cache_path[0] = '\0';
327         resource_path[0] = '\0';
328         shared_data_path[0] = '\0';
329         shared_resource_path[0] = '\0';
330         shared_trusted_path[0] = '\0';
331         external_data_path[0] = '\0';
332         external_cache_path[0] = '\0';
333         external_shared_data_path[0] = '\0';
334         pkgid[0] = '\0';
335 }
336
337 SLPAPI const char *aul_get_app_external_root_path(void)
338 {
339         if (external_root_path[0] == '\0') {
340                 char oldZone[64] = { 0, };
341
342                 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
343                 int ret = __get_root_path(external_root_path, _MAX_BASE_PATH_LEN - 1, true,
344                                           false);
345                 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
346                 if (ret != AUL_R_OK)
347                         return NULL;
348         }
349
350         return external_root_path;
351 }
352
353 SLPAPI const char *aul_get_app_root_path(void)
354 {
355         if (root_path[0] == '\0') {
356                 char oldZone[64] = { 0, };
357
358                 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
359                 int ret = __get_root_path(root_path, _MAX_BASE_PATH_LEN - 1, false, false);
360
361                 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
362
363                 if ( ret != AUL_R_OK)
364                         return NULL;
365         }
366         return root_path;
367 }
368
369 SLPAPI const char *aul_get_app_data_path(void)
370 {
371         if (data_path[0] == '\0') {
372                 char oldZone[64] = { 0, };
373
374                 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
375                 int ret = __get_path(data_path, _MAX_BASE_PATH_LEN - 1, _DATA_DIR, false, true);
376
377                 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
378
379                 if ( ret != AUL_R_OK)
380                         return NULL;
381         }
382         return data_path;
383 }
384
385 SLPAPI const char *aul_get_app_cache_path(void)
386 {
387         if (cache_path[0] == '\0') {
388                 char oldZone[64] = { 0, };
389
390                 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
391                 int ret = __get_path(cache_path, _MAX_BASE_PATH_LEN - 1, _CACHE_DIR, false,
392                                      true);
393
394                 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
395
396                 if ( ret != AUL_R_OK)
397                         return NULL;
398         }
399         return cache_path;
400 }
401
402 SLPAPI const char *aul_get_app_resource_path(void)
403 {
404         if (resource_path[0] == '\0') {
405                 char oldZone[64] = { 0, };
406
407                 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
408                 int ret = __get_path(resource_path, _MAX_BASE_PATH_LEN - 1, _RESOURCE_DIR,
409                                      false,
410                                      false);
411
412                 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
413
414                 if ( ret != AUL_R_OK)
415                         return NULL;
416         }
417         return resource_path;
418 }
419
420 SLPAPI const char *aul_get_app_tep_resource_path(void)
421 {
422         if (tep_resource_path[0] == '\0') {
423                 char oldZone[64] = { 0, };
424
425                 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
426                 int ret = __get_path(tep_resource_path, _MAX_BASE_PATH_LEN - 1, _TEP_RESOURCE_DIR,
427                                      false,
428                                      false);
429
430                 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
431
432                 if ( ret != AUL_R_OK)
433                         return NULL;
434         }
435         return tep_resource_path;
436 }
437
438 SLPAPI const char *aul_get_app_shared_data_path(void)
439 {
440         if (shared_data_path[0] == '\0') {
441                 char oldZone[64] = { 0, };
442
443                 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
444                 int ret = __get_path(shared_data_path, _MAX_BASE_PATH_LEN - 1, _SHARED_DATA_DIR,
445                                      false, true);
446
447                 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
448
449                 if ( ret != AUL_R_OK)
450                         return NULL;
451
452         }
453         return shared_data_path;
454 }
455
456 SLPAPI const char *aul_get_app_shared_resource_path(void)
457 {
458         if (shared_resource_path[0] == '\0') {
459                 char oldZone[64] = { 0, };
460
461                 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
462                 int ret = __get_path(shared_resource_path, _MAX_BASE_PATH_LEN - 1,
463                                      _SHARED_RESOURCE_DIR, false, false);
464
465                 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
466
467                 if ( ret != AUL_R_OK)
468                         return NULL;
469         }
470         return shared_resource_path;
471 }
472
473 SLPAPI const char *aul_get_app_shared_trusted_path(void)
474 {
475         if (shared_trusted_path[0] == '\0') {
476                 char oldZone[64] = { 0, };
477
478                 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
479                 int ret = __get_path(shared_trusted_path, _MAX_BASE_PATH_LEN - 1,
480                                      _SHARED_TRUSTED_DIR, false, true);
481
482                 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
483
484                 if ( ret != AUL_R_OK)
485                         return NULL;
486
487         }
488         return shared_trusted_path;
489 }
490
491 SLPAPI const char *aul_get_app_external_data_path(void)
492 {
493         if (external_data_path[0] == '\0') {
494                 char oldZone[64] = { 0, };
495
496                 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
497                 int ret = __get_path(external_data_path, _MAX_BASE_PATH_LEN - 1, _DATA_DIR,
498                                      true,
499                                      true);
500
501                 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
502
503                 if ( ret != AUL_R_OK)
504                         return NULL;
505
506         }
507         return external_data_path;
508 }
509
510 SLPAPI const char *aul_get_app_external_cache_path(void)
511 {
512         if (external_cache_path[0] == '\0') {
513                 char oldZone[64] = { 0, };
514
515                 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
516                 int ret = __get_path(external_cache_path, _MAX_BASE_PATH_LEN - 1, _CACHE_DIR,
517                                      true,
518                                      true);
519
520                 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
521
522                 if ( ret != AUL_R_OK)
523                         return NULL;
524
525         }
526         return external_cache_path;
527 }
528
529 SLPAPI const char *aul_get_app_external_shared_data_path(void)
530 {
531         if (external_shared_data_path[0] == '\0') {
532                 char oldZone[64] = { 0, };
533
534                 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
535                 int ret = __get_path(external_shared_data_path, _MAX_PACKAGE_ID_LEN - 1,
536                                      _SHARED_DATA_DIR, true, true);
537
538                 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
539
540                 if ( ret != AUL_R_OK)
541                         return NULL;
542
543         }
544         return external_shared_data_path;
545 }
546
547 SLPAPI const char *aul_get_app_specific_path(void)
548 {
549         const char *specific_path = NULL;
550         char oldZone[64] = { 0, };
551
552         if (pkgid[0] == '\0') {
553                 pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
554                 int err = __get_pkgid(pkgid, _MAX_PACKAGE_ID_LEN - 1);
555
556                 pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
557
558                 if (err != AUL_R_OK) {
559                         return NULL;
560                 }
561         }
562
563         pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
564         specific_path = __get_app_specific_path(pkgid);
565         pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
566
567         return specific_path;
568 }
569
570 SLPAPI const char *aul_get_app_external_specific_path(void)
571 {
572         return _EXTERNAL_APP_SPECIFIC_PATH;
573 }
574
575 SLPAPI int aul_get_app_shared_data_path_by_appid(const char *appid, char **path)
576 {
577         char oldZone[64] = { 0, };
578
579         pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
580         int ret = __get_path_by_appid(path, appid, _SHARED_DATA_DIR, false);
581         pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
582
583         return ret;
584 }
585
586 SLPAPI int aul_get_app_shared_resource_path_by_appid(const char *appid,
587         char **path)
588 {
589         char oldZone[64] = { 0, };
590
591         pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
592         int ret = __get_path_by_appid(path, appid, _SHARED_RESOURCE_DIR, false);
593         pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
594
595         return ret;
596 }
597
598 SLPAPI int aul_get_app_shared_trusted_path_by_appid(const char *appid,
599         char **path)
600 {
601         char oldZone[64] = { 0, };
602
603         pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
604         int ret = __get_path_by_appid(path, appid, _SHARED_TRUSTED_DIR, false);
605         pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
606
607         return ret;
608 }
609
610 SLPAPI int aul_get_app_external_shared_data_path_by_appid(const char *appid,
611         char **path)
612 {
613         char oldZone[64] = { 0, };
614
615         pkgmgrinfo_pkginfo_set_zone(_cur_zone, oldZone, 64);
616         int ret = __get_path_by_appid(path, appid, _SHARED_DATA_DIR, true);
617         pkgmgrinfo_pkginfo_set_zone(oldZone, NULL, 0);
618
619         return ret;
620 }
621
622 SLPAPI char *aul_get_cmdline_bypid(int pid)
623 {
624         return __proc_get_cmdline_bypid(pid);
625 }
626