tizen 2.4 release
[framework/base/rpm-installer.git] / backend / src / rpm / rpm-installer.c
1 /*
2  * rpm-installer
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7  * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #ifndef _GNU_SOURCE
24 #define _GNU_SOURCE
25 #endif
26 #define __USE_GNU
27 #include <sys/wait.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31 #include <wait.h>
32 #include <stdio.h>
33 #include <signal.h>
34 #include <errno.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <dirent.h>
38 #include <ctype.h>              /* for isspace () */
39 #include <wctype.h>             /* for towlower() */
40 #include <vconf.h>
41 #include <cert-service.h>
42 #include <libxml/parser.h>
43 #include <libxml/tree.h>
44 #include <libxml/xmlmemory.h>
45 #include <sqlite3.h>
46 #include <db-util.h>
47 #include <sys/xattr.h>
48
49 #ifndef XMLSEC_NO_XSLT
50 #include <libxslt/xslt.h>
51 #include <libxslt/security.h>
52 #endif
53
54 #include <xmlsec/xmlsec.h>
55 #include <xmlsec/xmltree.h>
56 #include <xmlsec/xmldsig.h>
57 #include <xmlsec/crypto.h>
58 #include <xmlsec/errors.h>
59 #include <pkgmgr-info.h>
60 #include <pkgmgr_parser.h>
61 #include <package-manager.h>
62 #include <privilege-control.h>
63 #include <app_manager.h>
64 #include <app_manager_extension.h>
65 #include <aul.h>
66 #include <dlfcn.h>
67 #define APP2EXT_ENABLE
68 #ifdef APP2EXT_ENABLE
69 #include <app2ext_interface.h>
70 #endif
71
72 #include "rpm-installer-signature.h"
73 #include "rpm-installer.h"
74 #include "rpm-frontend.h"
75 #include "installer-type.h"
76 #include "installer-util.h"
77 #include "coretpk-installer-internal.h"
78 #include "pkgmgr_parser_resource.h"
79
80 extern char *gpkgname;
81 extern int sig_enable;
82 char *sig1_capath;
83 int sig1_visibility;
84
85 static void __rpm_process_line(char *line);
86 static void __rpm_perform_read(int fd);
87 static int __ri_xmlsec_verify_signature(const char *sigxmlfile, char *rootca);
88 static xmlSecKeysMngrPtr __ri_load_trusted_certs(char *files, int files_size);
89 static int __ri_verify_file(xmlSecKeysMngrPtr mngr, const char *sigxmlfile);
90 static int __ri_create_cert_chain(int sigtype, int sigsubtype, char *value);
91 static void __ri_free_cert_chain(void);
92 static char *__ri_get_cert_from_file(const char *file);
93 static int __privilege_func(const char *name, void *user_data);
94 static void __ri_xmlsec_debug_print(const char *file, int line, const char *func, const char *errorObject, const char *errorSubject, int reason, const char *msg);
95
96 int _ri_set_group_id(const char *pkgid, const char *groupid);
97
98 static void __str_trim(char *input)
99 {
100         char *trim_str = input;
101
102         if (input == NULL)
103                 return;
104
105         while (*input != 0) {
106                 if (!isspace(*input)) {
107                         *trim_str = *input;
108                         trim_str++;
109                 }
110                 input++;
111         }
112
113         *trim_str = 0;
114         return;
115 }
116
117 static int __ri_get_op_type(char *op_str)
118 {
119         if (strcmp(op_str, "install") == 0)
120                 return INSTALL_REQ;
121         else if (strcmp(op_str, "update") == 0)
122                 return UPGRADE_REQ;
123         else if (strcmp(op_str, "uninstall") == 0)
124                 return UNINSTALL_REQ;
125         else
126                 return -1;
127 }
128
129 int __get_version_from_xml(char* manifest, char** version){
130
131         const char *val = NULL;
132         const xmlChar *node;
133         xmlTextReaderPtr reader;
134         int ret = PMINFO_R_OK;
135
136         if(manifest == NULL) {
137                 _LOGE("Input argument is NULL\n");
138                 return PMINFO_R_ERROR;
139         }
140
141         if(version == NULL) {
142                 _LOGE("Argument supplied to hold return value is NULL\n");
143                 return PMINFO_R_ERROR;
144         }
145
146         reader = xmlReaderForFile(manifest, NULL, 0);
147
148         if (reader){
149                 if ( _child_element(reader, -1)) {
150                         node = xmlTextReaderConstName(reader);
151                         if (!node) {
152                                 _LOGE("xmlTextReaderConstName value is NULL\n");
153                                 ret =  PMINFO_R_ERROR;
154                                 goto end;
155                         }
156
157                         if (!strcmp(ASCII(node), "manifest")) {
158                                 ret = _ri_get_attribute(reader, "version", &val);
159                                 if(ret != 0){
160                                         _LOGE("@Error in getting attribute value");
161                                         ret = PMINFO_R_ERROR;
162                                         goto end;
163                                 }
164
165                                 if(val){
166                                         *version = strdup(val);
167                                         if(*version == NULL){
168                                                 _LOGE("Malloc Failed!!");
169                                                 ret = PMINFO_R_ERROR;
170                                                 goto end;
171                                         }
172                                 }
173                         } else {
174                                 _LOGE("Unable to create xml reader\n");
175                                 ret =  PMINFO_R_ERROR;
176                         }
177                 }
178         } else {
179                 _LOGE("xmlReaderForFile value is NULL\n");
180                 return PMINFO_R_ERROR;
181         }
182
183 end:
184         xmlFreeTextReader(reader);
185
186         if(val)
187                 free((void*)val);
188
189         return ret;
190 }
191
192 static int __ri_init_csc_xml(char *xml_path, char *removable)
193 {
194         int ret = 0;
195         char *csc_tags[3] = { NULL, };
196
197         if (strcmp(removable, "true") == 0)
198                 csc_tags[0] = "removable=true";
199         else
200                 csc_tags[0] = "removable=false";
201
202         csc_tags[1] = "preload=true";
203         csc_tags[2] = NULL;
204
205         ret = pkgmgr_parser_parse_manifest_for_installation(xml_path, csc_tags);
206
207         return ret;
208 }
209
210 static int __ri_create_cert_chain(int sigtype, int sigsubtype, char *value)
211 {
212         if (value == NULL)
213                 return -1;
214         /* _LOGD("Push in list [%d] [%d] [%s]", sigtype, sigsubtype, value); */
215         switch (sigtype) {
216         case SIG_AUTH:
217                 switch (sigsubtype) {
218                 case SIG_SIGNER:
219                         list[PMINFO_SET_AUTHOR_SIGNER_CERT].cert_type = PMINFO_SET_AUTHOR_SIGNER_CERT;
220                         list[PMINFO_SET_AUTHOR_SIGNER_CERT].cert_value = strdup(value);
221                         break;
222                 case SIG_INTERMEDIATE:
223                         list[PMINFO_SET_AUTHOR_INTERMEDIATE_CERT].cert_type = PMINFO_SET_AUTHOR_INTERMEDIATE_CERT;
224                         list[PMINFO_SET_AUTHOR_INTERMEDIATE_CERT].cert_value = strdup(value);
225                         break;
226                 case SIG_ROOT:
227                         /* value is already a mallocd pointer */
228                         list[PMINFO_SET_AUTHOR_ROOT_CERT].cert_type = PMINFO_SET_AUTHOR_ROOT_CERT;
229                         list[PMINFO_SET_AUTHOR_ROOT_CERT].cert_value = value;
230                         break;
231                 default:
232                         break;
233                 }
234                 break;
235         case SIG_DIST1:
236                 switch (sigsubtype) {
237                 case SIG_SIGNER:
238                         list[PMINFO_SET_DISTRIBUTOR_SIGNER_CERT].cert_type = PMINFO_SET_DISTRIBUTOR_SIGNER_CERT;
239                         list[PMINFO_SET_DISTRIBUTOR_SIGNER_CERT].cert_value = strdup(value);
240                         break;
241                 case SIG_INTERMEDIATE:
242                         list[PMINFO_SET_DISTRIBUTOR_INTERMEDIATE_CERT].cert_type = PMINFO_SET_DISTRIBUTOR_INTERMEDIATE_CERT;
243                         list[PMINFO_SET_DISTRIBUTOR_INTERMEDIATE_CERT].cert_value = strdup(value);
244                         break;
245                 case SIG_ROOT:
246                         /* value is already a mallocd pointer */
247                         list[PMINFO_SET_DISTRIBUTOR_ROOT_CERT].cert_type = PMINFO_SET_DISTRIBUTOR_ROOT_CERT;
248                         list[PMINFO_SET_DISTRIBUTOR_ROOT_CERT].cert_value = value;
249                         break;
250                 default:
251                         break;
252                 }
253                 break;
254         case SIG_DIST2:
255                 switch (sigsubtype) {
256                 case SIG_SIGNER:
257                         list[PMINFO_SET_DISTRIBUTOR2_SIGNER_CERT].cert_type = PMINFO_SET_DISTRIBUTOR2_SIGNER_CERT;
258                         list[PMINFO_SET_DISTRIBUTOR2_SIGNER_CERT].cert_value = strdup(value);
259                         break;
260                 case SIG_INTERMEDIATE:
261                         list[PMINFO_SET_DISTRIBUTOR2_INTERMEDIATE_CERT].cert_type = PMINFO_SET_DISTRIBUTOR2_INTERMEDIATE_CERT;
262                         list[PMINFO_SET_DISTRIBUTOR2_INTERMEDIATE_CERT].cert_value = strdup(value);
263                         break;
264                 case SIG_ROOT:
265                         /* value is already a mallocd pointer */
266                         list[PMINFO_SET_DISTRIBUTOR2_ROOT_CERT].cert_type = PMINFO_SET_DISTRIBUTOR2_ROOT_CERT;
267                         list[PMINFO_SET_DISTRIBUTOR2_ROOT_CERT].cert_value = value;
268                         break;
269                 default:
270                         break;
271                 }
272                 break;
273         default:
274                 break;
275         }
276
277         return 0;
278 }
279
280 static void __ri_free_cert_chain()
281 {
282         int i = 0;
283         for (i = 0; i < MAX_CERT_NUM; i++) {
284                 if (list[i].cert_value) {
285                         free(list[i].cert_value);
286                         list[i].cert_value = NULL;
287                 }
288         }
289 }
290
291 static void __ri_xmlsec_debug_print(const char *file, int line, const char *func, const char *errorObject, const char *errorSubject, int reason, const char *msg)
292 {
293         _SLOGE("[%s(%d)] : [%s] : [%s] : [%d] : [%s]", func, line, errorObject, errorSubject, reason, msg);
294 }
295
296 static int __ri_verify_file(xmlSecKeysMngrPtr sec_key_mngr, const char *sigxmlfile)
297 {
298         xmlDocPtr doc = NULL;
299         xmlNodePtr node = NULL;
300         xmlSecDSigCtxPtr dsigCtx = NULL;
301         int res = -1;
302         if (sigxmlfile == NULL)
303                 return -1;
304         if (sec_key_mngr == NULL)
305                 return -1;
306
307         /* set error callback to xmlsec1 */
308         xmlSecErrorsSetCallback(__ri_xmlsec_debug_print);
309
310         /* load file */
311         doc = xmlParseFile(sigxmlfile);
312         if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)) {
313                 _LOGE("unable to parse file \"%s\"\n", sigxmlfile);
314                 goto err;
315         }
316         /* find start node */
317         node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
318         if (node == NULL) {
319                 _LOGE("start node not found in \"%s\"\n", sigxmlfile);
320                 goto err;
321         }
322         /* create signature context */
323         dsigCtx = xmlSecDSigCtxCreate(sec_key_mngr);
324         if (dsigCtx == NULL) {
325                 _LOGE("failed to create signature context\n");
326                 goto err;
327         }
328         /* Verify signature */
329         if (xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
330                 _LOGE("failed to verify signature\n");
331                 goto err;
332         }
333         /* print verification result to stdout */
334         if (dsigCtx->status == xmlSecDSigStatusSucceeded) {
335                 res = 0;
336                 _LOGD("valid signature");
337         } else {
338                 res = -1;
339                 _LOGD("invalid signature");
340         }
341
342 err:
343         /* cleanup */
344         if (dsigCtx != NULL) {
345                 xmlSecDSigCtxDestroy(dsigCtx);
346         }
347         if (doc != NULL) {
348                 xmlFreeDoc(doc);
349         }
350         return res;
351 }
352
353 static xmlSecKeysMngrPtr __ri_load_trusted_certs(char *files, int files_size)
354 {
355         xmlSecKeysMngrPtr sec_key_mngr;
356         if (files == NULL)
357                 return NULL;
358
359         if (files_size < 0)
360                 return NULL;
361
362         sec_key_mngr = xmlSecKeysMngrCreate();
363         if (sec_key_mngr == NULL) {
364                 _LOGE("failed to create keys manager.\n");
365                 return NULL;
366         }
367
368         if (xmlSecCryptoAppDefaultKeysMngrInit(sec_key_mngr) < 0) {
369                 _LOGE("failed to initialize keys manager.\n");
370                 xmlSecKeysMngrDestroy(sec_key_mngr);
371                 return NULL;
372         }
373
374         /* load trusted cert */
375         if (xmlSecCryptoAppKeysMngrCertLoad(sec_key_mngr, files, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) {
376                 _LOGE("failed to load pem certificate from \"%s\"\n", files);
377                 xmlSecKeysMngrDestroy(sec_key_mngr);
378                 return NULL;
379         }
380
381         return sec_key_mngr;
382 }
383
384 static int __ri_xmlsec_verify_signature(const char *sigxmlfile, char *rootca)
385 {
386         int ret = 0;
387         xmlSecKeysMngrPtr sec_key_mngr = NULL;
388         xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
389         xmlSubstituteEntitiesDefault(1);
390
391 #ifndef XMLSEC_NO_XSLT
392         xmlIndentTreeOutput = 1;
393         xsltSecurityPrefsPtr sec_prefs = xsltNewSecurityPrefs();
394         xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid);
395         xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid);
396         xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid);
397         xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid);
398         xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid);
399         xsltSetDefaultSecurityPrefs(sec_prefs);
400 #endif
401
402         ret = xmlSecInit();
403         if (ret < 0) {
404                 _LOGE("xmlsec initialization failed [%d]\n", ret);
405                 goto end;
406         }
407         ret = xmlSecCheckVersion();
408         if (ret != 1) {
409                 _LOGE("Incompatible version of loaded xmlsec library [%d]\n", ret);
410                 goto end;
411         }
412 #ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
413         ret = xmlSecCryptoDLLoadLibrary(BAD_CAST "openssl");
414         if (ret < 0) {
415                 _LOGE("unable to load openssl library [%d]\n", ret);
416                 goto end;
417         }
418 #endif
419
420         ret = xmlSecCryptoAppInit(NULL);
421         if (ret < 0) {
422                 _LOGE("crypto initialization failed [%d]\n", ret);
423                 goto end;
424         }
425         ret = xmlSecCryptoInit();
426         if (ret < 0) {
427                 _LOGE("xmlsec-crypto initialization failed [%d]\n", ret);
428                 goto end;
429         }
430
431         sec_key_mngr = __ri_load_trusted_certs(rootca, 1);
432         if (sec_key_mngr == NULL) {
433                 _LOGE("loading of trusted certs failed\n");
434                 ret = -1;
435                 goto end;
436         }
437
438         if (__ri_verify_file(sec_key_mngr, sigxmlfile) < 0) {
439                 ret = -1;
440         }
441
442 end:
443         if (sec_key_mngr)
444                 xmlSecKeysMngrDestroy(sec_key_mngr);
445
446         xmlSecCryptoShutdown();
447         xmlSecCryptoAppShutdown();
448         xmlSecShutdown();
449 #ifndef XMLSEC_NO_XSLT
450         xsltFreeSecurityPrefs(sec_prefs);
451         xsltCleanupGlobals();
452 #endif
453
454         return ret;
455 }
456
457 int _rpm_installer_get_group_id(const char *pkgid, char **result)
458 {
459         int ret = 0;
460         const char *value = NULL;
461         char author_signature[BUF_SIZE] = { '\0' };
462         char *e_rootcert = NULL;
463         char *d_rootcert = NULL;
464         gsize d_size = 0;
465         unsigned char hashout[BUF_SIZE] = { '\0' };
466         unsigned int h_size = 0;
467         int e_size = 0;
468         int length = 0;
469         pkgmgrinfo_certinfo_h handle = NULL;
470
471         snprintf(author_signature, BUF_SIZE, "%s/%s/%s", USR_APPS, pkgid, AUTHOR_SIGNATURE_XML);
472         if (access(author_signature, F_OK) != 0) {
473                 _LOGE("[%s] isn't existed.", author_signature);
474                 return -1;
475         }
476
477         ret = pkgmgrinfo_pkginfo_create_certinfo(&handle);
478         if (ret < 0) {
479                 _LOGE("pkgmgrinfo_pkginfo_create_certinfo(%s) failed.", pkgid);
480                 goto err;
481         }
482
483         ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid, handle);
484         if (ret < 0) {
485                 _LOGE("pkgmgrinfo_pkginfo_load_certinfo(%s) failed.", pkgid);
486                 goto err;
487         }
488
489         /* get root certificate */
490         ret = pkgmgrinfo_pkginfo_get_cert_value(handle, PMINFO_AUTHOR_SIGNER_CERT, &value);
491         if (ret < 0 || value == NULL) {
492                 _LOGE("pkgmgrinfo_pkginfo_get_cert_value(%s) failed. [%d]", pkgid, ret);
493                 goto err;
494         }
495
496         /* decode cert */
497         d_rootcert = (char *)g_base64_decode(value, &d_size);
498         if (d_rootcert == NULL) {
499                 _LOGE("g_base64_decode() failed.");
500                 goto err;
501         }
502         _LOGD("g_base64_decode() succeed, d_size=[%d]", d_size);
503
504         /* hash */
505         EVP_Digest(d_rootcert, d_size, hashout, &h_size, EVP_sha1(), NULL);
506         if (h_size <= 0) {
507                 _LOGE("EVP_Digest(hash) failed.");
508                 goto err;
509         }
510         _LOGD("EVP_Digest() succeed, h_size=[%d]", h_size);
511
512         /* encode cert */
513         e_rootcert = g_base64_encode((const guchar *)hashout, h_size);
514         if (e_rootcert == NULL) {
515                 _LOGE("g_base64_encode() failed.");
516                 goto err;
517         }
518         e_size = strlen(e_rootcert);
519         _LOGD("g_base64_encode() succeed, e_size=[%d]", e_size);
520
521         /* replace / to # */
522         for (length = e_size; length >= 0; --length) {
523                 if (e_rootcert[length] == '/') {
524                         e_rootcert[length] = '#';
525                 }
526         }
527
528         *result = e_rootcert;
529
530 err:
531         if (d_rootcert) {
532                 free(d_rootcert);
533         }
534
535         /* destroy cert */
536         if (handle) {
537                 pkgmgrinfo_pkginfo_destroy_certinfo(handle);
538         }
539
540         return ret;
541 }
542
543 void __rpm_apply_smack(const char *pkgname, int flag, char *smack_label)
544 {
545         int ret = -1;
546         char dirpath[BUF_SIZE] = { '\0' };
547         char *groupid = NULL;
548         char *shared_data_label = NULL;
549         char buf[BUF_SIZE] = { 0, };
550
551         if (smack_label == NULL || strlen(smack_label) == 0) {
552                 smack_label = (char *)pkgname;
553         }
554
555         /* execute privilege APIs. The APIs should not fail */
556         _ri_privilege_register_package(smack_label);
557
558         /* home dir. Dont setup path but change smack access to "_" */
559         snprintf(dirpath, BUF_SIZE, "%s/%s", USR_APPS, pkgname);
560         if (__is_dir(dirpath))
561                 _ri_privilege_change_smack_label(dirpath, "_", 0);      /* 0 is SMACK_LABEL_ACCESS */
562         memset(dirpath, '\0', BUF_SIZE);
563         snprintf(dirpath, BUF_SIZE, "%s/%s", OPT_USR_APPS, pkgname);
564         if (__is_dir(dirpath))
565                 _ri_privilege_change_smack_label(dirpath, "_", 0);      /* 0 is SMACK_LABEL_ACCESS */
566
567         /* data */
568         memset(dirpath, '\0', BUF_SIZE);
569         snprintf(dirpath, BUF_SIZE, "%s/%s/data", OPT_USR_APPS, pkgname);
570         if (!__is_dir(dirpath)) {
571                 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
572                 if (ret < 0) {
573                         _LOGE("directory making is failed.\n");
574                 }
575         }
576
577         ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
578         if (ret != 0) {
579                 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
580                         _LOGE("chown failed!! [%s]", buf);
581                 }
582         }
583         _ri_privilege_setup_path(smack_label, dirpath, APP_PATH_PRIVATE, smack_label);
584
585         /* cache */
586         memset(dirpath, '\0', BUF_SIZE);
587         snprintf(dirpath, BUF_SIZE, "%s/%s/cache", OPT_USR_APPS, pkgname);
588         if (!__is_dir(dirpath)) {
589                 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
590                 if (ret < 0) {
591                         _LOGE("directory making is failed.\n");
592                 }
593         }
594         ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
595         if (ret != 0) {
596                 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
597                         _LOGE("chown failed!! [%s]", buf);
598                 }
599         }
600         _ri_privilege_setup_path(smack_label, dirpath, APP_PATH_PRIVATE, smack_label);
601
602         /* shared */
603         memset(dirpath, '\0', BUF_SIZE);
604         snprintf(dirpath, BUF_SIZE, "%s/%s/shared", USR_APPS, pkgname);
605         if (__is_dir(dirpath))
606                 _ri_privilege_change_smack_label(dirpath, "_", 0);      /* 0 is SMACK_LABEL_ACCESS */
607         memset(dirpath, '\0', BUF_SIZE);
608         snprintf(dirpath, BUF_SIZE, "%s/%s/shared", OPT_USR_APPS, pkgname);
609         if (!__is_dir(dirpath)) {
610                 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
611                 if (ret < 0)
612                         _LOGE("directory making is failed.\n");
613         }
614         _ri_privilege_change_smack_label(dirpath, "_", 0);      /* 0 is SMACK_LABEL_ACCESS */
615         memset(dirpath, '\0', BUF_SIZE);
616
617         /* shared/res */
618         snprintf(dirpath, BUF_SIZE, "%s/%s/shared/res", USR_APPS, pkgname);
619         if (__is_dir(dirpath))
620                 _ri_privilege_setup_path(smack_label, dirpath, PERM_APP_PATH_ANY_LABEL, "_");
621         memset(dirpath, '\0', BUF_SIZE);
622
623         snprintf(dirpath, BUF_SIZE, "%s/%s/shared/res", OPT_USR_APPS, pkgname);
624         if (__is_dir(dirpath))
625                 _ri_privilege_setup_path(smack_label, dirpath, PERM_APP_PATH_ANY_LABEL, "_");
626         memset(dirpath, '\0', BUF_SIZE);
627
628         /* shared/data */
629         snprintf(dirpath, BUF_SIZE, "%s/%s/shared/data", USR_APPS, pkgname);
630         if (__is_dir(dirpath)) {
631                 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
632                 if (ret != 0) {
633                         if( strerror_r(errno, buf, sizeof(buf)) == 0) {
634                                 _LOGE("chown failed!! [%s]", buf);
635                         }
636                 }
637                 _ri_privilege_setup_path(smack_label, dirpath, PERM_APP_PATH_PUBLIC, NULL);
638         }
639         memset(dirpath, '\0', BUF_SIZE);
640
641         snprintf(dirpath, BUF_SIZE, "%s/%s/shared/data", OPT_USR_APPS, pkgname);
642         if (__is_dir(dirpath)) {
643                 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
644                 if (ret != 0) {
645                         if( strerror_r(errno, buf, sizeof(buf)) == 0) {
646                                 _LOGE("chown failed!! [%s]", buf);
647                         }
648                 }
649                 _ri_privilege_setup_path(smack_label, dirpath, PERM_APP_PATH_PUBLIC, NULL);
650         }
651
652         /* shared/cache */
653         ret = _coretpk_installer_get_smack_label_access(dirpath, &shared_data_label);
654         if (ret != 0) {
655                 _LOGE("_coretpk_installer_apply_directory_policy() failed, appdir=[%s], ret=[%d]", dirpath, ret);
656         }
657         memset(dirpath, '\0', BUF_SIZE);
658         snprintf(dirpath, BUF_SIZE, "%s/%s/shared/cache", OPT_USR_APPS, pkgname);
659         if (!__is_dir(dirpath)) {
660                 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
661                 if (ret < 0) {
662                         _LOGE("directory making is failed.\n");
663                 }
664         }
665         ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
666         if (ret != 0) {
667                 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
668                         _LOGE("chown failed!! [%s]", buf);
669                 }
670         }
671         ret = _coretpk_installer_set_smack_label_access(dirpath, shared_data_label);
672         if (ret != 0) {
673                 _LOGE("_coretpk_installer_apply_directory_policy() failed, appdir=[%s], ret=[%d]", dirpath, ret);
674         }
675         ret = _coretpk_installer_set_smack_label_transmute(dirpath, "1");
676         if (ret != 0) {
677                 _LOGE("_coretpk_installer_apply_directory_policy() failed, appdir=[%s], ret=[%d]", dirpath, ret);
678         }
679
680         /* /shared/trusted/ */
681         memset(dirpath, '\0', BUF_SIZE);
682         snprintf(dirpath, BUF_SIZE, "%s/%s/shared/trusted", USR_APPS, pkgname);
683         if (__is_dir(dirpath)) {
684                 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
685                 if (ret != 0) {
686                         if( strerror_r(errno, buf, sizeof(buf)) == 0) {
687                                 _LOGE("chown failed!! [%s]", buf);
688                         }
689                 }
690
691                 ret = _rpm_installer_get_group_id(pkgname, &groupid);
692                 if (ret == 0) {
693                         _LOGD("group id for trusted directory is [%s]", groupid);
694                         _ri_privilege_setup_path(smack_label, dirpath, APP_PATH_GROUP_RW, groupid);
695                         FREE_AND_NULL(groupid);
696                 }
697         }
698         memset(dirpath, '\0', BUF_SIZE);
699
700         snprintf(dirpath, BUF_SIZE, "%s/%s/shared/trusted", OPT_USR_APPS, pkgname);
701
702         _LOGD("dirpath [%s]", dirpath);
703
704         ret = _rpm_installer_get_group_id(pkgname, &groupid);
705         if (ret == 0) {
706                 if (__is_dir(dirpath) != 1) {
707                         _LOGE("dont have [%s]", dirpath);
708
709                         ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
710                         if (ret == -1 && errno != EEXIST) {
711                                 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
712                                         _LOGE("mkdir failed!! [%s]", buf);
713                                 }
714                         }
715                 }
716
717                 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
718                 if (ret != 0) {
719                         if( strerror_r(errno, buf, sizeof(buf)) == 0) {
720                                 _LOGE("chown failed!! [%s]", buf);
721                         }
722                 }
723
724                 _LOGD("group id for trusted directory is [%s]", groupid);
725                 _ri_privilege_setup_path(smack_label, dirpath, APP_PATH_GROUP_RW, groupid);
726                 _ri_set_group_id(pkgname, groupid);
727
728                 FREE_AND_NULL(groupid);
729         }
730 }
731
732 int __is_dir(const char *dirname)
733 {
734         struct stat stFileInfo;
735         if (dirname == NULL) {
736                 _LOGE("dirname is null\n");
737                 return 0;
738         }
739
740         if (stat(dirname, &stFileInfo) < 0) {
741                 return 0;
742         }
743
744         if (S_ISDIR(stFileInfo.st_mode)) {
745                 return 1;
746         }
747         return 0;
748 }
749
750 static void __rpm_process_line(char *line)
751 {
752         char *tok = NULL;
753         char *save_str = NULL;
754         tok = strtok_r(line, " ", &save_str);
755         if (tok) {
756                 if (!strncmp(tok, "%%", 2)) {
757                         tok = strtok_r(NULL, " ", &save_str);
758                         if (tok) {
759                                 _LOGD("Install percentage is %s\n", tok);
760                                 _ri_broadcast_status_notification(gpkgname, PKGTYPE_RPM, "install_percent", tok);
761                                 _ri_stat_cb(gpkgname, "install_percent", tok);
762                         }
763                         return;
764                 }
765         }
766         return;
767 }
768
769 static void __rpm_perform_read(int fd)
770 {
771         char *buf_ptr = NULL;
772         char *tmp_ptr = NULL;
773         int size = 0;
774         static char buffer[BUF_SIZE] = { 0, };
775         static int buffer_position;
776
777         size = read(fd, &buffer[buffer_position], sizeof(buffer) - buffer_position);
778         buffer_position += size;
779         if (size <= 0)
780                 return;
781
782         /* Process each line of the recieved buffer */
783         buf_ptr = tmp_ptr = buffer;
784         while ((tmp_ptr = (char *)memchr(buf_ptr, '\n', buffer + buffer_position - buf_ptr)) != NULL) {
785                 *tmp_ptr = 0;
786                 __rpm_process_line(buf_ptr);
787                 /* move to next line and continue */
788                 buf_ptr = tmp_ptr + 1;
789         }
790
791         /* move the remaining bits at the start of the buffer
792            and update the buffer position */
793         buf_ptr = (char *)memrchr(buffer, 0, buffer_position);
794         if (buf_ptr == NULL)
795                 return;
796
797         /* we have processed till the last \n which has now become
798            0x0. So we increase the pointer to next position */
799         buf_ptr++;
800
801         memmove(buffer, buf_ptr, buf_ptr - buffer);
802         buffer_position = buffer + buffer_position - buf_ptr;
803 }
804
805 int _rpm_xsystem(const char *argv[])
806 {
807         int err = 0;
808         int status = 0;
809         pid_t pid;
810         int pipefd[2];
811         int result = 0;
812         int fd = 0;
813
814         if (pipe(pipefd) == -1) {
815                 _LOGE("pipe creation failed\n");
816                 return -1;
817         }
818         /* Read progress info via pipe */
819         pid = fork();
820
821         switch (pid) {
822         case -1:
823                 _LOGE("fork failed\n");
824                 return -1;
825         case 0:
826                 /* child */
827                 close(pipefd[0]);
828                 close(1);
829                 close(2);
830                 fd = dup(pipefd[1]);
831                 if (fd < 0) {
832                         _LOGE("dup failed\n");
833                         _exit(100);
834                 }
835
836                 result = dup(pipefd[1]);
837                 if (result < 0) {
838                         _LOGE("dup failed\n");
839                         _exit(100);
840                 }
841
842                 if (execvp(argv[0], (char *const *)argv) == -1) {
843                         _LOGE("execvp failed\n");
844                 }
845                 _exit(100);
846         default:
847                 /* parent */
848                 break;
849         }
850
851         close(pipefd[1]);
852
853         while ((err = waitpid(pid, &status, WNOHANG)) != pid) {
854                 if (err < 0) {
855                         if (errno == EINTR)
856                                 continue;
857                         _LOGE("waitpid failed\n");
858                         close(pipefd[0]);
859                         return -1;
860                 }
861
862                 int select_ret;
863                 fd_set rfds;
864                 struct timespec tv;
865                 FD_ZERO(&rfds);
866                 FD_SET(pipefd[0], &rfds);
867                 tv.tv_sec = 1;
868                 tv.tv_nsec = 0;
869                 select_ret = pselect(pipefd[0] + 1, &rfds, NULL, NULL, &tv, NULL);
870                 if (select_ret == 0)
871                         continue;
872
873                 else if (select_ret < 0 && errno == EINTR)
874                         continue;
875                 else if (select_ret < 0) {
876                         _LOGE("select() returned error\n");
877                         continue;
878                 }
879                 if (FD_ISSET(pipefd[0], &rfds))
880                         __rpm_perform_read(pipefd[0]);
881         }
882
883         close(pipefd[0]);
884         /* Check for an error code. */
885         if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0) {
886                 if (WIFSIGNALED(status) != 0 && WTERMSIG(status) == SIGSEGV) {
887                         printf("Sub-process %s received a segmentation fault. \n", argv[0]);
888                 } else if (WIFEXITED(status) != 0) {
889                         printf("Sub-process %s returned an error code (%u)\n", argv[0], WEXITSTATUS(status));
890                 } else {
891                         printf("Sub-process %s exited unexpectedly\n", argv[0]);
892                 }
893         }
894         return WEXITSTATUS(status);
895 }
896
897 void __rpm_clear_dir_list(GList *dir_list)
898 {
899         GList *list = NULL;
900         app2ext_dir_details *dir_detail = NULL;
901         if (dir_list) {
902                 list = g_list_first(dir_list);
903                 while (list) {
904                         dir_detail = (app2ext_dir_details *) list->data;
905                         if (dir_detail && dir_detail->name) {
906                                 free(dir_detail->name);
907                         }
908                         g_free(list->data);
909                         list = g_list_next(list);
910                 }
911                 g_list_free(dir_list);
912         }
913 }
914
915 GList *__rpm_populate_dir_list()
916 {
917         GList *dir_list = NULL;
918         GList *list = NULL;
919         app2ext_dir_details *dir_detail = NULL;
920         int i;
921         char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
922
923         for (i = 0; i < 3; i++) {
924                 dir_detail = (app2ext_dir_details *) calloc(1, sizeof(app2ext_dir_details));
925                 if (dir_detail == NULL) {
926                         printf("\nMemory allocation failed\n");
927                         goto FINISH_OFF;
928                 }
929                 dir_detail->name = (char *)calloc(1, sizeof(char) * (strlen(pkg_ro_content_rpm[i]) + 2));
930                 if (dir_detail->name == NULL) {
931                         printf("\nMemory allocation failed\n");
932                         free(dir_detail);
933                         goto FINISH_OFF;
934                 }
935                 snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i]) + 1), "%s", pkg_ro_content_rpm[i]);
936                 dir_detail->type = APP2EXT_DIR_RO;
937                 dir_list = g_list_append(dir_list, dir_detail);
938         }
939         if (dir_list) {
940                 list = g_list_first(dir_list);
941                 while (list) {
942                         dir_detail = (app2ext_dir_details *) list->data;
943                         list = g_list_next(list);
944                 }
945         }
946
947         return dir_list;
948
949 FINISH_OFF:
950         if (dir_list) {
951                 list = g_list_first(dir_list);
952                 while (list) {
953                         dir_detail = (app2ext_dir_details *) list->data;
954                         if (dir_detail && dir_detail->name) {
955                                 free(dir_detail->name);
956                         }
957                         g_free(list->data);
958                         list = g_list_next(list);
959                 }
960                 g_list_free(dir_list);
961         }
962
963         return NULL;
964 }
965
966 static char *__ri_get_cert_from_file(const char *file)
967 {
968         FILE *fp_cert = NULL;
969         int certlen = 0;
970         char *certbuf = NULL;
971         char *startcert = NULL;
972         char *endcert = NULL;
973         int certwrite = 0;
974         char *cert = NULL;
975         int i = 0;
976         int ch = 0;
977         int error = 0;
978
979         if (!(fp_cert = fopen(file, "r"))) {
980                 _LOGE("[ERR][%s] Fail to open file, [%s]\n", __func__, file);
981                 return NULL;
982         }
983
984         fseek(fp_cert, 0L, SEEK_END);
985
986         if (ftell(fp_cert) < 0) {
987                 _LOGE("[ERR][%s] Fail to find EOF\n", __func__);
988                 error = 1;
989                 goto err;
990         }
991
992         certlen = ftell(fp_cert);
993         if (certlen < 0) {
994                 _LOGE("[ERR][%s] Fail to find EOF\n", __func__);
995                 error = 1;
996                 goto err;
997         }
998
999         fseek(fp_cert, 0L, SEEK_SET);
1000
1001         if (!(certbuf = (char *)malloc(sizeof(char) * (int)certlen))) {
1002                 _LOGE("[ERR][%s] Fail to allocate memory\n", __func__);
1003                 error = 1;
1004                 goto err;
1005         }
1006         memset(certbuf, 0x00, (int)certlen);
1007
1008         i = 0;
1009         while ((ch = fgetc(fp_cert)) != EOF) {
1010                 if (ch != '\n') {
1011                         certbuf[i] = ch;
1012                         i++;
1013                 }
1014         }
1015         certbuf[i] = '\0';
1016
1017         startcert = strstr(certbuf, "-----BEGIN CERTIFICATE-----") + strlen("-----BEGIN CERTIFICATE-----");
1018         endcert = strstr(certbuf, "-----END CERTIFICATE-----");
1019         certwrite = (int)endcert - (int)startcert;
1020
1021         cert = (char *)malloc(sizeof(char) * (certwrite + 2));
1022         if (cert == NULL) {
1023                 _LOGE("[ERR][%s] Fail to allocate memory\n", __func__);
1024                 error = 1;
1025                 goto err;
1026         }
1027         memset(cert, 0x00, certwrite + 2);
1028         snprintf(cert, certwrite + 1, "%s", startcert);
1029         _LOGD("Root CA, len=[%d]\n%s", certwrite, cert);
1030
1031 err:
1032         if (certbuf)
1033                 free(certbuf);
1034         fclose(fp_cert);
1035         if (error)
1036                 return NULL;
1037         else
1038                 return cert;
1039 }
1040
1041 static int __privilege_func(const char *name, void *user_data)
1042 {
1043         int ret = 0;
1044         privilegeinfo *info = (privilegeinfo *) user_data;
1045
1046         _LOGD("package_id=[%s], privilege=[%s]", info->package_id, name);
1047         info->privileges = g_list_append(info->privileges, strdup((char *)name));
1048
1049         if (strcmp(name, EXT_APPDATA_PRIVILEGE_NAME) == 0) {
1050                 _LOGD("it is EXT_APPDATA_PRIVILEGE_NAME");
1051                 if (_coretpk_installer_make_directory_for_ext((char *)info->package_id) < 0) {
1052                         _LOGE("make_directory_for_ext failed.");
1053                 }
1054         }
1055
1056         return ret;
1057 }
1058
1059 char *__strlwr(char *str)
1060 {
1061         int i = 0;
1062
1063         while (*(str + i) != '\0') {
1064                 if (*(str + i) >= 65 || *(str + i) <= 90) {
1065                         *(str + i) = towlower(*(str + i));
1066                 }
1067                 i++;
1068         }
1069         return str;
1070 }
1071
1072 static char *__getvalue(const char *pBuf, const char *pKey)
1073 {
1074         const char *p = NULL;
1075         const char *pStart = NULL;
1076         const char *pEnd = NULL;
1077
1078         p = strstr(pBuf, pKey);
1079         if (p == NULL)
1080                 return NULL;
1081
1082         pStart = p + strlen(pKey) + 1;
1083         pEnd = strchr(pStart, SEPERATOR_START);
1084         if (pEnd == NULL)
1085                 return NULL;
1086
1087         size_t len = pEnd - pStart;
1088         if (len <= 0)
1089                 return NULL;
1090
1091         char *pRes = (char *)malloc(len + 1);
1092         if (pRes == NULL) {
1093                 _LOGE("@malloc failed");
1094                 return NULL;
1095         }
1096         strncpy(pRes, pStart, len);
1097         pRes[len] = 0;
1098
1099         return pRes;
1100 }
1101
1102 static char *__find_rpm_pkgid(const char *manifest)
1103 {
1104         FILE *fp = NULL;
1105         char buf[BUF_SIZE] = { 0 };
1106         char *pkgid = NULL;
1107
1108         fp = fopen(manifest, "r");
1109         if (fp == NULL) {
1110                 _LOGE("csc-info : Fail get : %s\n", manifest);
1111                 return NULL;
1112         }
1113
1114         while (fgets(buf, BUF_SIZE, fp) != NULL) {
1115                 __str_trim(buf);
1116                 pkgid = __getvalue(buf, TOKEN_PACKAGE_STR);
1117                 if (pkgid != NULL) {
1118                         fclose(fp);
1119                         return pkgid;
1120                 }
1121                 memset(buf, 0x00, BUF_SIZE);
1122         }
1123
1124         if (fp != NULL)
1125                 fclose(fp);
1126
1127         return NULL;
1128 }
1129
1130 static int __copy_file(const char *src_path, const char *dst_path)
1131 {
1132         FILE *src, *dst;
1133         int rc = 0;
1134         unsigned char temp_buf[8192] = { '\0', };
1135         size_t size_of_uchar = sizeof(unsigned char);
1136         size_t size_of_temp_buf = sizeof(temp_buf);
1137         char buf[BUF_SIZE] = { 0, };
1138
1139         src = fopen(src_path, "r");
1140         if (src == NULL) {
1141                 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
1142                         _LOGE("Failed to open(). path=%s, E:%d(%s)", src_path, errno, buf);
1143                 }
1144                 return -1;
1145         }
1146
1147         dst = fopen(dst_path, "w");
1148         if (dst == NULL) {
1149                 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
1150                         _LOGE("Failed to open dst file. file=%s, E:%d(%s)", dst_path, errno, buf);
1151                 }
1152                 fclose(src);
1153                 return -1;
1154         }
1155
1156         while (!feof(src)) {
1157                 rc = fread(temp_buf, size_of_uchar, size_of_temp_buf, src);
1158                 fwrite(temp_buf, size_of_uchar, rc, dst);
1159         }
1160
1161         fclose(src);
1162         fclose(dst);
1163         return 0;
1164 }
1165
1166 static int __ri_install_csc(char *path_str, char *remove_str)
1167 {
1168         int ret = 0;
1169         char *pkgid = NULL;
1170         char delims[] = "/";
1171         char *token = NULL;
1172         char argv[BUF_SIZE] = { '\0' };
1173         char xml_name[BUF_SIZE] = { '\0' };
1174         char src_file[BUF_SIZE] = { '\0' };
1175         char dest_file[BUF_SIZE] = { '\0' };
1176         char *save_str = NULL;
1177
1178         snprintf(src_file, sizeof(src_file), "%s", path_str);
1179
1180         /* get pkgid from path str */
1181         pkgid = __find_rpm_pkgid(path_str);
1182         if (pkgid == NULL) {
1183                 _LOGE("csc-info : fail to find pkgid\n");
1184                 return -1;
1185         }
1186         _LOGD("csc-info : find pkgid=[%s] for installation\n", pkgid);
1187
1188         /* find xml name */
1189         token = strtok_r(path_str, delims, &save_str);
1190         while (token) {
1191                 memset(xml_name, 0x00, sizeof(xml_name));
1192                 strncat(xml_name, token, sizeof(xml_name) - 1);
1193                 token = strtok_r(NULL, delims, &save_str);
1194         }
1195         _LOGD("csc-info : xml name = %s\n", xml_name);
1196
1197         /* copy xml to /opt/share/packages */
1198         snprintf(dest_file, sizeof(dest_file), "%s/%s", OPT_SHARE_PACKAGES, xml_name);
1199         ret = __copy_file(src_file, dest_file);
1200         if (ret != 0) {
1201                 _LOGE("csc-info : xml copy fail(%d)\n", ret);
1202         } else {
1203                 _LOGE("csc-info : xml copy success to [%s] \n", dest_file);
1204         }
1205
1206         /* remove old pkg info */
1207         ret = pkgmgr_parser_parse_manifest_for_uninstallation(pkgid, NULL);
1208         if (ret < 0) {
1209                 _LOGD("csc-info : fail remove old pkg info\n");
1210         } else {
1211                 _LOGD("csc-info : success remove old pkg info\n");
1212         }
1213
1214         /* insert new pkg info */
1215         memset(argv, 0x00, sizeof(argv));
1216         snprintf(argv, sizeof(argv), "%s/%s", OPT_SHARE_PACKAGES, xml_name);
1217         ret = __ri_init_csc_xml(argv, remove_str);
1218         if (ret < 0) {
1219                 _LOGD("csc-info : fail insert db\n");
1220         } else {
1221                 _LOGD("csc-info : success xml name = %s\n", xml_name);
1222         }
1223         if (pkgid) {
1224                 free(pkgid);
1225                 pkgid = NULL;
1226         }
1227
1228         return 0;
1229 }
1230
1231 static int __ri_uninstall_csc(char *pkgid)
1232 {
1233         /* remove old pkg info */
1234         int ret = pkgmgr_parser_parse_manifest_for_uninstallation(pkgid, NULL);
1235         if (ret < 0) {
1236                 _LOGD("csc-info : fail remove old pkg info\n");
1237         } else {
1238                 _LOGD("csc-info : success remove old pkg info\n");
1239         }
1240
1241         return 0;
1242 }
1243
1244 static int __get_size_from_xml(const char *manifest, int *size)
1245 {
1246         const char *val = NULL;
1247         const xmlChar *node;
1248         xmlTextReaderPtr reader;
1249         int ret = PMINFO_R_OK;
1250
1251         if (manifest == NULL) {
1252                 _LOGE("Input argument is NULL\n");
1253                 return PMINFO_R_ERROR;
1254         }
1255
1256         if (size == NULL) {
1257                 _LOGE("Argument supplied to hold return value is NULL\n");
1258                 return PMINFO_R_ERROR;
1259         }
1260
1261         reader = xmlReaderForFile(manifest, NULL, 0);
1262
1263         if (reader) {
1264                 if (_child_element(reader, -1)) {
1265                         node = xmlTextReaderConstName(reader);
1266                         if (!node) {
1267                                 _LOGE("xmlTextReaderConstName value is NULL\n");
1268                                 ret = PMINFO_R_ERROR;
1269                                 goto end;
1270                         }
1271
1272                         if (!strcmp(ASCII(node), "manifest")) {
1273                                 ret = _ri_get_attribute(reader, "size", &val);
1274                                 if (ret != 0) {
1275                                         _LOGE("@Error in getting the attribute value");
1276                                         ret = PMINFO_R_ERROR;
1277                                         goto end;
1278                                 }
1279                                 if (val) {
1280                                         *size = atoi(val);
1281                                         free((void *)val);
1282                                 } else {
1283                                         *size = 0;
1284                                         _LOGE("package size is not specified\n");
1285                                         ret = PMINFO_R_ERROR;
1286                                         goto end;
1287                                 }
1288                         } else {
1289                                 _LOGE("Unable to create xml reader\n");
1290                                 ret = PMINFO_R_ERROR;
1291                                 goto end;
1292                         }
1293                 }
1294         } else {
1295                 _LOGE("xmlReaderForFile value is NULL\n");
1296                 ret = PMINFO_R_ERROR;
1297         }
1298
1299 end:
1300         xmlFreeTextReader(reader);
1301         return ret;
1302 }
1303
1304 static int __get_location_from_xml(const char *manifest, pkgmgrinfo_install_location * location)
1305 {
1306         const char *val = NULL;
1307         const xmlChar *node;
1308         xmlTextReaderPtr reader;
1309         int ret = -1;
1310
1311         if (manifest == NULL) {
1312                 _LOGE("Input argument is NULL\n");
1313                 return PMINFO_R_ERROR;
1314         }
1315
1316         if (location == NULL) {
1317                 _LOGE("Argument supplied to hold return value is NULL\n");
1318                 return PMINFO_R_ERROR;
1319         }
1320
1321         reader = xmlReaderForFile(manifest, NULL, 0);
1322
1323         if (reader) {
1324                 if (_child_element(reader, -1)) {
1325                         node = xmlTextReaderConstName(reader);
1326                         if (!node) {
1327                                 _LOGE("xmlTextReaderConstName value is NULL\n");
1328                                 xmlFreeTextReader(reader);
1329                                 return PMINFO_R_ERROR;
1330                         }
1331
1332                         if (!strcmp(ASCII(node), "manifest")) {
1333                                 ret = _ri_get_attribute(reader, "install-location", &val);
1334                                 if (ret != 0) {
1335                                         _LOGE("@Error in getting the attribute value");
1336                                         xmlFreeTextReader(reader);
1337                                         return PMINFO_R_ERROR;
1338                                 }
1339
1340                                 if (val) {
1341                                         if (strcmp(val, "internal-only") == 0)
1342                                                 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
1343                                         else if (strcmp(val, "prefer-external") == 0)
1344                                                 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
1345                                         else
1346                                                 *location = PMINFO_INSTALL_LOCATION_AUTO;
1347                                         free((void *)val);
1348                                 }
1349                         } else {
1350                                 _LOGE("Unable to create xml reader\n");
1351                                 xmlFreeTextReader(reader);
1352                                 return PMINFO_R_ERROR;
1353                         }
1354                 }
1355         } else {
1356                 _LOGE("xmlReaderForFile value is NULL\n");
1357                 return PMINFO_R_ERROR;
1358         }
1359
1360         xmlFreeTextReader(reader);
1361
1362         return PMINFO_R_OK;
1363 }
1364
1365 static char *__get_pkg_path(const char *pkg_path, const char *pkgid)
1366 {
1367         int ret = 0;
1368         char buff[BUF_SIZE] = { '\0' };
1369         char *real_path = NULL;
1370         char buf[BUF_SIZE] = { 0, };
1371
1372         snprintf(buff, BUF_SIZE, "%s/%s", pkg_path, pkgid);
1373         do {
1374                 if (__is_dir(buff))
1375                         break;
1376                 memset(buff, '\0', BUF_SIZE);
1377                 snprintf(buff, BUF_SIZE, "%s/%s", USR_APPS, pkgid);
1378                 if (__is_dir(buff))
1379                         break;
1380                 memset(buff, '\0', BUF_SIZE);
1381                 snprintf(buff, BUF_SIZE, "/opt/apps/%s", pkgid);
1382                 if (__is_dir(buff))
1383                         break;
1384                 memset(buff, '\0', BUF_SIZE);
1385                 snprintf(buff, BUF_SIZE, "%s/%s", OPT_USR_APPS, pkgid);
1386                 if (__is_dir(buff))
1387                         break;
1388         } while (0);
1389
1390         ret = chdir(buff);
1391         if (ret != 0) {
1392                 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
1393                         _LOGE("chdir(%s) failed. [%s]", buff, buf);
1394                 }
1395                 return NULL;
1396         }
1397
1398         real_path = (char *)malloc(strlen(buff) + 1);
1399         if (real_path == NULL) {
1400                 _LOGE("malloc() failed.");
1401                 return NULL;
1402         }
1403         memset(real_path, '\0', strlen(buff) + 1);
1404         memcpy(real_path, buff, strlen(buff));
1405
1406         return real_path;
1407 }
1408
1409 void _ri_register_cert(const char *pkgid)
1410 {
1411         int error = 0;
1412         pkgmgrinfo_instcertinfo_h handle = NULL;
1413         int i = 0;
1414         /* create Handle */
1415         error = pkgmgrinfo_create_certinfo_set_handle(&handle);
1416         if (error != 0) {
1417                 _LOGE("Cert handle creation failed. Err:%d", error);
1418                 __ri_free_cert_chain();
1419                 return;
1420         }
1421
1422         if (list[SIG_AUTH].cert_value == NULL) {
1423                 _LOGE("pkgid[%s] dont have SIG_AUTH.cert_value ", pkgid);
1424                 goto err;
1425         }
1426
1427         for (i = 0; i < MAX_CERT_NUM; i++) {
1428
1429                 if (list[i].cert_value) {
1430                         error = pkgmgrinfo_set_cert_value(handle, list[i].cert_type, list[i].cert_value);
1431                         if (error != 0) {
1432                                 _LOGE("pkgmgrinfo_set_cert_value failed. cert type:%d. Err:%d", list[i].cert_type, error);
1433                                 goto err;
1434                         }
1435                 }
1436         }
1437         /* Save the certificates in cert DB */
1438         error = pkgmgrinfo_save_certinfo(pkgid, handle);
1439         if (error != 0) {
1440                 _LOGE("pkgmgrinfo_save_certinfo failed. Err:%d", error);
1441                 goto err;
1442         }
1443 err:
1444         if (handle)
1445                 pkgmgrinfo_destroy_certinfo_set_handle(handle);
1446         __ri_free_cert_chain();
1447 }
1448
1449 void _ri_unregister_cert(const char *pkgid)
1450 {
1451         int error = 0;
1452         /* Delete the certifictes from cert DB */
1453         error = pkgmgrinfo_delete_certinfo(pkgid);
1454         if (error != 0) {
1455                 _LOGE("pkgmgrinfo_delete_certinfo failed. Err:%d", error);
1456                 return;
1457         }
1458 }
1459
1460 int _ri_get_visibility_from_signature_file(const char *sigfile, int *visibility, bool save_ca_path)
1461 {
1462         char certval[BUF_SIZE] = { '\0' };
1463         int err = 0;
1464         int i = 0;
1465         int j = 0;
1466         int ret = RPM_INSTALLER_SUCCESS;
1467         signature_x *signx = NULL;
1468         struct keyinfo_x *keyinfo = NULL;
1469         struct x509data_x *x509data = NULL;
1470         CERT_CONTEXT *ctx = NULL;
1471         int validity = 0;
1472
1473         if (sigfile == NULL) {
1474                 return RPM_INSTALLER_ERR_WRONG_PARAM;
1475         }
1476
1477         ctx = cert_svc_cert_context_init();
1478         if (ctx == NULL) {
1479                 _LOGE("cert_svc_cert_context_init() failed.");
1480                 return RPM_INSTALLER_ERR_INTERNAL;
1481         }
1482
1483         if (!strstr(sigfile, SIGNATURE1_XML)) {
1484                 _LOGE("Unsupported signature type! [%s]", sigfile);
1485                 cert_svc_cert_context_final(ctx);
1486                 return RPM_INSTALLER_ERR_INTERNAL;
1487         }
1488
1489         signx = _ri_process_signature_xml(sigfile);
1490         if (signx == NULL) {
1491                 _LOGE("_ri_process_signature_xml(%s) failed.", sigfile);
1492                 ret = RPM_INSTALLER_ERR_INTERNAL;
1493                 goto end;
1494         }
1495
1496         keyinfo = signx->keyinfo;
1497         if ((keyinfo == NULL) || (keyinfo->x509data == NULL)
1498                 || (keyinfo->x509data->x509certificate == NULL)) {
1499                 _LOGE("keyinfo is invalid. [%s]", sigfile);
1500                 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1501                 goto end;
1502         }
1503
1504         x509data = keyinfo->x509data;
1505         x509certificate_x *cert = x509data->x509certificate;
1506
1507         /* First cert is Signer certificate */
1508         if (cert->text != NULL) {
1509                 for (i = 0; i <= (int)strlen(cert->text); i++) {
1510                         if (cert->text[i] != '\n') {
1511                                 certval[j++] = cert->text[i];
1512                         }
1513                 }
1514                 certval[j] = '\0';
1515
1516                 err = cert_svc_load_buf_to_context(ctx, (unsigned char *)certval);
1517                 if (err != 0) {
1518                         _LOGE("cert_svc_load_buf_to_context() failed. err = [%d]", err);
1519                         _SLOGE("cert_svc_load_buf_to_context() failed. cert = [%s]", certval);
1520                         ret = RPM_INSTALLER_ERR_INTERNAL;
1521                         goto end;
1522                 }
1523
1524                 if (save_ca_path) {
1525                         err = __ri_create_cert_chain(SIG_DIST1, SIG_SIGNER, certval);
1526                         if (err) {
1527                                 _LOGE("__ri_create_cert_chain() failed. sigtype = [%d]", (int)SIG_DIST1);
1528                                 _SLOGE("__ri_create_cert_chain() failed. cert = [%s]", certval);
1529                                 __ri_free_cert_chain();
1530                                 ret = RPM_INSTALLER_ERR_INTERNAL;
1531                                 goto end;
1532                         }
1533                 }
1534         }
1535
1536         /* Second cert is Intermediate certificate */
1537         cert = cert->next;
1538         if ((cert != NULL) && (cert->text != NULL)) {
1539                 memset(certval, 0x00, BUF_SIZE);
1540                 j = 0;
1541                 for (i = 0; i <= (int)strlen(cert->text); i++) {
1542                         if (cert->text[i] != '\n') {
1543                                 certval[j++] = cert->text[i];
1544                         }
1545                 }
1546                 certval[j] = '\0';
1547
1548                 if (cert->text != NULL) {
1549                         err = cert_svc_push_buf_into_context(ctx, (unsigned char *)certval);
1550                         if (err != 0) {
1551                                 _LOGE("cert_svc_push_buf_into_context() failed. cert = [%s], err = [%d]", certval, err);
1552                                 ret = RPM_INSTALLER_ERR_INTERNAL;
1553                                 goto end;
1554                         }
1555                 }
1556
1557                 if (save_ca_path) {
1558                         err = __ri_create_cert_chain(SIG_DIST1, SIG_INTERMEDIATE, certval);
1559                         if (err) {
1560                                 _LOGE("__ri_create_cert_chain() failed. sigtype = [%d]", (int)SIG_DIST1);
1561                                 _SLOGE("__ri_create_cert_chain() failed. cert = [%s]", certval);
1562                                 __ri_free_cert_chain();
1563                                 ret = RPM_INSTALLER_ERR_INTERNAL;
1564                                 goto end;
1565                         }
1566                 }
1567         } else {
1568                 _LOGE("Invalid CertChain! (cert->text is NULL.)");
1569                 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1570                 goto end;
1571         }
1572
1573         err = cert_svc_verify_package_certificate(ctx, &validity, sigfile);
1574
1575         if (err != 0) {
1576                 _LOGE("cert_svc_verify_package_certificate() failed.");
1577                 ret = RPM_INSTALLER_ERR_INTERNAL;
1578                 goto end;
1579         }
1580         if (validity == 0) {
1581                 _LOGE("Certificate Invalid/Expired (validity == 0)");
1582                 ret = RPM_INSTALLER_ERR_CERTCHAIN_VERIFICATION_FAILED;
1583                 goto end;
1584         }
1585         _LOGD("cert_svc_verify() is done successfully. validity=[%d]", validity);
1586
1587         err = cert_svc_get_visibility(ctx, visibility);
1588         if (err != 0) {
1589                 _LOGE("cert_svc_get_visibility() failed. err = [%d]", err);
1590                 ret = RPM_INSTALLER_ERR_SIG_VERIFICATION_FAILED;
1591                 goto end;
1592         }
1593         ret = 0;
1594
1595         if (save_ca_path && ctx->fileNames && ctx->fileNames->filename) {
1596                 FREE_AND_NULL(sig1_capath);
1597                 sig1_capath = strdup(ctx->fileNames->filename);
1598                 sig1_visibility = *visibility;
1599         }
1600
1601 end:
1602         cert_svc_cert_context_final(ctx);
1603         ctx = NULL;
1604         _ri_free_signature_xml(signx);
1605         signx = NULL;
1606         return ret;
1607 }
1608
1609 int _ri_verify_sig_and_cert(const char *sigfile, int *visibility, bool need_verify, char *ca_path)
1610 {
1611         char certval[BUF_SIZE] = { '\0' };
1612         int err = 0;
1613         int validity = 0;
1614         int i = 0;
1615         int j = 0;
1616         int ret = RPM_INSTALLER_SUCCESS;
1617         char *crt = NULL;
1618         signature_x *signx = NULL;
1619         struct keyinfo_x *keyinfo = NULL;
1620         struct x509data_x *x509data = NULL;
1621         CERT_CONTEXT *ctx = NULL;
1622         int sigtype = 0;
1623         char *root_ca_path = NULL;
1624
1625         ctx = cert_svc_cert_context_init();
1626         if (ctx == NULL) {
1627                 _LOGE("cert_svc_cert_context_init() failed.");
1628                 return RPM_INSTALLER_ERR_INTERNAL;
1629         }
1630
1631         if (strstr(sigfile, AUTHOR_SIGNATURE_XML))
1632                 sigtype = SIG_AUTH;
1633         else if (strstr(sigfile, SIGNATURE1_XML))
1634                 sigtype = SIG_DIST1;
1635         else if (strstr(sigfile, SIGNATURE2_XML))
1636                 sigtype = SIG_DIST2;
1637         else {
1638                 _LOGE("Unsupported signature type! [%s]", sigfile);
1639                 cert_svc_cert_context_final(ctx);
1640                 return RPM_INSTALLER_ERR_SIG_INVALID;
1641         }
1642
1643         if (sigtype == SIG_DIST1 && ca_path != NULL && strlen(ca_path) != 0) {
1644                 root_ca_path = ca_path;
1645                 *visibility = sig1_visibility;
1646                 goto verify_sig;
1647         }
1648
1649         signx = _ri_process_signature_xml(sigfile);
1650         if (signx == NULL) {
1651                 _LOGE("_ri_process_signature_xml(%s) failed.", sigfile);
1652                 ret = RPM_INSTALLER_ERR_SIG_INVALID;
1653                 goto end;
1654         }
1655
1656         keyinfo = signx->keyinfo;
1657         if ((keyinfo == NULL) || (keyinfo->x509data == NULL) || (keyinfo->x509data->x509certificate == NULL)) {
1658                 _LOGE("keyinfo is invalid. [%s]", sigfile);
1659                 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1660                 goto end;
1661         }
1662
1663         x509data = keyinfo->x509data;
1664         x509certificate_x *cert = x509data->x509certificate;
1665
1666         /* First cert is Signer certificate */
1667         if (cert->text != NULL) {
1668                 for (i = 0; i <= (int)strlen(cert->text); i++) {
1669                         if (cert->text[i] != '\n') {
1670                                 certval[j++] = cert->text[i];
1671                         }
1672                 }
1673                 certval[j] = '\0';
1674
1675                 err = cert_svc_load_buf_to_context(ctx, (unsigned char *)certval);
1676                 if (err != 0) {
1677                         _LOGE("cert_svc_load_buf_to_context() failed. err = [%d]", err);
1678                         _SLOGE("cert_svc_load_buf_to_context() failed. cert = [%s]", certval);
1679                         ret = RPM_INSTALLER_ERR_CERT_INVALID;
1680                         goto end;
1681                 }
1682
1683                 err = __ri_create_cert_chain(sigtype, SIG_SIGNER, certval);
1684                 if (err) {
1685                         _LOGE("__ri_create_cert_chain() failed. sigtype = [%d]", sigtype);
1686                         _SLOGE("__ri_create_cert_chain() failed. cert = [%s]", certval);
1687                         __ri_free_cert_chain();
1688                         ret = RPM_INSTALLER_ERR_CERT_INVALID;
1689                         goto end;
1690                 }
1691         } else {
1692                 _LOGE("cert->text is NULL. [Signer]");
1693                 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1694                 goto end;
1695         }
1696
1697         /* Second cert is Intermediate certificate */
1698         cert = cert->next;
1699         if (cert == NULL) {
1700                 _LOGE("cert is NULL. [Intermediate]");
1701                 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1702                 goto end;
1703         }
1704
1705         if (cert->text != NULL) {
1706                 memset(certval, 0x00, BUF_SIZE);
1707                 j = 0;
1708                 for (i = 0; i <= (int)strlen(cert->text); i++) {
1709                         if (cert->text[i] != '\n') {
1710                                 certval[j++] = cert->text[i];
1711                         }
1712                 }
1713                 certval[j] = '\0';
1714
1715                 if (cert->text != NULL) {
1716                         err = cert_svc_push_buf_into_context(ctx, (unsigned char *)certval);
1717                         if (err != 0) {
1718                                 _LOGE("cert_svc_push_buf_into_context() failed. cert = [%s], err = [%d]", certval, err);
1719                                 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1720                                 goto end;
1721                         }
1722                 }
1723
1724                 err = __ri_create_cert_chain(sigtype, SIG_INTERMEDIATE, certval);
1725                 if (err) {
1726                         _LOGE("__ri_create_cert_chain() failed. sigtype = [%d]", sigtype);
1727                         _SLOGE("__ri_create_cert_chain() failed. cert = [%s]", certval);
1728                         __ri_free_cert_chain();
1729                         ret = RPM_INSTALLER_ERR_CERT_INVALID;
1730                         goto end;
1731                 }
1732         } else {
1733                 _LOGE("Invalid CertChain! (cert->text is NULL.) [Intermediate]");
1734                 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1735                 goto end;
1736         }
1737
1738         err = cert_svc_verify_package_certificate(ctx, &validity, sigfile);
1739         if (err != 0 && (need_verify == true)) {
1740                 _LOGE("cert_svc_verify_package_certificate() failed. err=[%d]", err);
1741                 ret = err;
1742                 goto end;
1743         }
1744         _LOGD("cert_svc_verify() is done successfully. validity=[%d]", validity);
1745
1746         if (validity == 0) {
1747                 _LOGE("Certificate Invalid/Expired (validity == 0)");
1748                 ret = RPM_INSTALLER_ERR_CERTIFICATE_EXPIRED;
1749                 goto end;
1750         }
1751
1752         err = cert_svc_get_visibility(ctx, visibility);
1753         if (err != 0) {
1754                 _LOGE("cert_svc_get_visibility() failed. err = [%d]", err);
1755                 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1756                 goto end;
1757         }
1758         _LOGD("cert_svc_get_visibility() returns visibility=[%d]", *visibility);
1759
1760         if (ctx->fileNames == NULL || ctx->fileNames->filename == NULL) {
1761                 _LOGE("No Root CA cert found. Signature validation failed.");
1762                 ret = RPM_INSTALLER_ERR_ROOT_CERT_NOT_FOUND;
1763                 goto end;
1764         } else
1765                 root_ca_path = ctx->fileNames->filename;
1766
1767 verify_sig:
1768         /* verify signature
1769            For reference validation, we should be in TEMP_DIR/usr/apps/<pkgid> */
1770         if (root_ca_path != NULL && strlen(root_ca_path) != 0) {
1771                 _LOGD("Root CA cert path=[%s]", root_ca_path);
1772
1773                 if (need_verify == true) {
1774                         err = __ri_xmlsec_verify_signature(sigfile, root_ca_path);
1775                         if (err < 0) {
1776                                 _LOGE("__ri_xmlsec_verify_signature(%s) failed.", sigfile);
1777                                 ret = RPM_INSTALLER_ERR_SIG_VERIFICATION_FAILED;
1778                                 goto end;
1779                         }
1780                 }
1781
1782                 crt = __ri_get_cert_from_file(root_ca_path);
1783                 err = __ri_create_cert_chain(sigtype, SIG_ROOT, crt);
1784                 if (err) {
1785                         _LOGE("__ri_create_cert_chain() failed. sigtype = [%d]", sigtype);
1786                         _SLOGE("__ri_create_cert_chain() failed. cert = [%s]", crt);
1787                         __ri_free_cert_chain();
1788                         ret = RPM_INSTALLER_ERR_CERT_INVALID;
1789                         goto end;
1790                 }
1791
1792         }
1793         ret = 0;
1794
1795 end:
1796         cert_svc_cert_context_final(ctx);
1797         ctx = NULL;
1798         _ri_free_signature_xml(signx);
1799         signx = NULL;
1800         return ret;
1801 }
1802
1803 int _ri_verify_signatures(const char *root_path, const char *pkgid, bool need_verify)
1804 {
1805         int ret = 0;
1806         char buff[BUF_SIZE] = { '\0' };
1807         char *pkg_path = NULL;
1808         int visibility = 0;
1809
1810         _LOGD("root_path=[%s], pkgid=[%s]", root_path, pkgid);
1811
1812         /* check for signature and certificate */
1813         pkg_path = __get_pkg_path(root_path, pkgid);
1814         if (pkg_path == NULL) {
1815                 _LOGE("__get_pkg_path(%s, %s) failed.", root_path, pkgid);
1816                 return 0;
1817         }
1818
1819         _LOGD("switched to pkg_path=[%s]", pkg_path);
1820
1821         /* author-signature.xml is mandatory */
1822         snprintf(buff, BUF_SIZE, "%s/author-signature.xml", pkg_path);
1823         if (access(buff, F_OK) == 0) {
1824                 _LOGD("author-signature.xml, path=[%s]", buff);
1825                 ret = _ri_verify_sig_and_cert(buff, &visibility, need_verify, NULL);
1826                 if (ret) {
1827                         _LOGE("_ri_verify_sig_and_cert(%s) failed.", buff);
1828                         ret = -1;
1829                         goto end;
1830                 }
1831                 _LOGD("------------------------------------------------------");
1832                 _LOGD("signature is verified successfully");
1833                 _LOGD("path=[%s]", buff);
1834                 _LOGD("------------------------------------------------------");
1835         }
1836         memset(buff, '\0', BUF_SIZE);
1837
1838         /* signature2.xml is optional */
1839         snprintf(buff, BUF_SIZE, "%s/signature2.xml", pkg_path);
1840         if (access(buff, F_OK) == 0) {
1841                 _LOGD("signature2.xml found. [%s]", pkg_path);
1842                 ret = _ri_verify_sig_and_cert(buff, &visibility, need_verify, NULL);
1843                 if (ret) {
1844                         _LOGE("_ri_verify_sig_and_cert(%s) failed.", buff);
1845                         ret = -1;
1846                         goto end;
1847                 }
1848                 _LOGD("_ri_verify_sig_and_cert(%s) succeed.", buff);
1849         }
1850         memset(buff, '\0', BUF_SIZE);
1851
1852         /* signature1.xml is mandatory */
1853         snprintf(buff, BUF_SIZE, "%s/signature1.xml", pkg_path);
1854         if (access(buff, F_OK) == 0) {
1855                 _LOGD("signature1.xml, path=[%s]", buff);
1856                 ret = _ri_verify_sig_and_cert(buff, &visibility, need_verify, NULL);
1857                 if (ret) {
1858                         _LOGE("_ri_verify_sig_and_cert(%s) failed.", buff);
1859                         ret = -1;
1860                         goto end;
1861                 }
1862                 _LOGD("------------------------------------------------------");
1863                 _LOGD("signature is verified successfully");
1864                 _LOGD("path=[%s]", buff);
1865                 _LOGD("------------------------------------------------------");
1866         }
1867         memset(buff, '\0', BUF_SIZE);
1868
1869         ret = 0;
1870
1871 end:
1872         if (pkg_path) {
1873                 free(pkg_path);
1874                 pkg_path = NULL;
1875         }
1876
1877         if ((ret != 0) && (sig_enable == 0)) {
1878                 _LOGD("_ri_verify_signatures(%s, %s) failed, but it's ok for config.", root_path, pkgid);
1879                 ret = 0;
1880         }
1881
1882         return ret;
1883 }
1884
1885 void _ri_apply_smack(const char *pkgname, int flag, char *smack_label)
1886 {
1887         __rpm_apply_smack(pkgname, flag, smack_label);
1888 }
1889
1890 int _ri_apply_privilege(const char *pkgid, int visibility, char *smack_label)
1891 {
1892         int ret = -1;
1893         pkgmgrinfo_pkginfo_h handle = NULL;
1894         privilegeinfo info;
1895         int apptype = PERM_APP_TYPE_EFL;
1896         int i = 0;
1897         char *privilege_fota[BUF_SIZE] = { NULL, };
1898         char *api_version = NULL;
1899         GList *list = NULL;
1900
1901         if (smack_label == NULL || strlen(smack_label) == 0) {
1902                 smack_label = (char *)pkgid;
1903         }
1904
1905         memset(&info, '\0', sizeof(info));
1906
1907         ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
1908         if (ret != PMINFO_R_OK) {
1909                 _LOGE("pkgmgrinfo_pkginfo_get_pkginfo(%s) failed.", pkgid);
1910                 return -1;
1911         }
1912
1913         ret = pkgmgrinfo_pkginfo_get_api_version(handle, &api_version);
1914         if (ret != PMINFO_R_OK)
1915                 _LOGE("failed to get api version (%s)", pkgid);
1916
1917         if (api_version) {
1918                 ret = _ri_privilege_set_package_version(smack_label, api_version);
1919                 if (ret != 0) {
1920                         _LOGE("failed to set api version for smack_label: %s, ret[%d]", smack_label, ret);
1921                         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1922                         return -1;
1923                 } else
1924                         _LOGD("api-version[%s] fot privilege has done successfully.", api_version);
1925         }
1926
1927         strncpy(info.package_id, pkgid, sizeof(info.package_id) - 1);
1928         info.visibility = visibility;
1929
1930         ret = pkgmgrinfo_pkginfo_foreach_privilege(handle, __privilege_func, (void *)&info);
1931         if (ret != PMINFO_R_OK) {
1932                 _LOGE("pkgmgrinfo_pkginfo_foreach_privilege(%s) failed.", pkgid);
1933                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1934                 return -1;
1935         }
1936         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1937
1938         if (visibility & CERT_SVC_VISIBILITY_PLATFORM) {
1939                 _LOGD("VISIBILITY_PLATFORM!");
1940                 apptype = PERM_APP_TYPE_EFL_PLATFORM;
1941         } else if ((visibility & CERT_SVC_VISIBILITY_PARTNER) ||
1942                 (visibility & CERT_SVC_VISIBILITY_PARTNER_OPERATOR) ||
1943                 (visibility & CERT_SVC_VISIBILITY_PARTNER_MANUFACTURER)) {
1944                 _LOGD("VISIBILITY_PARTNER!");
1945                 apptype = PERM_APP_TYPE_EFL_PARTNER;
1946         }
1947
1948         list = g_list_first(info.privileges);
1949
1950         while (list) {
1951                 privilege_fota[i] = strdup((char *)list->data);
1952                 i++;
1953                 list = g_list_next(list);
1954         }
1955
1956         privilege_fota[i] = NULL;
1957
1958         ret = _ri_privilege_enable_permissions(smack_label, apptype, (const char **)privilege_fota, 1);
1959         for (i = 0; i < g_list_length(info.privileges); i++) {
1960                 if (privilege_fota[i]) {
1961                         free(privilege_fota[i]);
1962                         privilege_fota[i] = NULL;
1963                 }
1964         }
1965
1966         if (info.privileges != NULL) {
1967                 list = g_list_first(info.privileges);
1968                 while (list) {
1969                         if (list->data) {
1970                                 free(list->data);
1971                         }
1972                         list = g_list_next(list);
1973                 }
1974                 g_list_free(info.privileges);
1975                 info.privileges = NULL;
1976         }
1977
1978         if (ret < 0) {
1979                 _LOGE("_ri_privilege_enable_permissions(%s, %d) failed.", smack_label, apptype);
1980                 return -1;
1981         }
1982
1983         return 0;
1984 }
1985
1986 int _ri_set_group_id(const char *pkgid, const char *groupid)
1987 {
1988         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "pkgid is NULL\n");
1989         retvm_if(groupid == NULL, PMINFO_R_EINVAL, "groupid is NULL\n");
1990         int ret = -1;
1991         sqlite3 *pkginfo_db = NULL;
1992         char *query = NULL;
1993
1994         /* open db */
1995         ret = db_util_open(PKGMGR_DB, &pkginfo_db, 0);
1996         retvm_if(ret != SQLITE_OK, PMINFO_R_ERROR, "connect db [%s] failed!", PKGMGR_DB);
1997
1998         /* Begin transaction */
1999         ret = sqlite3_exec(pkginfo_db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
2000         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Failed to begin transaction\n");
2001         _LOGD("Transaction Begin\n");
2002
2003         query = sqlite3_mprintf("update package_info set package_reserve3=%Q where package=%Q", groupid, pkgid);
2004
2005         ret = sqlite3_exec(pkginfo_db, query, NULL, NULL, NULL);
2006         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
2007
2008         /* Commit transaction */
2009         ret = sqlite3_exec(pkginfo_db, "COMMIT", NULL, NULL, NULL);
2010         if (ret != SQLITE_OK) {
2011                 _LOGE("Failed to commit transaction. Rollback now\n");
2012                 ret = sqlite3_exec(pkginfo_db, "ROLLBACK", NULL, NULL, NULL);
2013                 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
2014         }
2015         _LOGD("Transaction Commit and End\n");
2016
2017         ret = PMINFO_R_OK;
2018 catch:
2019         sqlite3_free(query);
2020         sqlite3_close(pkginfo_db);
2021
2022         return ret;
2023 }
2024
2025 /**
2026  * callback for the pkgmgrinfo_appinfo_get_list used in _rpm_uninstall_pkg()
2027  */
2028 int __ri_check_running_app(const pkgmgrinfo_appinfo_h handle, void *user_data)
2029 {
2030         int ret = 0;
2031         bool isRunning = 0;
2032         char *appid = NULL;
2033         app_context_h appCtx = NULL;
2034
2035         ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
2036         if (ret < 0) {
2037                 _LOGE("Failed to execute pkgmgrinfo_appinfo_get_appid[%d].\n", ret);
2038                 return ret;
2039         }
2040
2041         if (user_data != NULL)
2042                 *(GList **)user_data = g_list_append(*(GList **)user_data, strdup(appid));
2043
2044         ret = app_manager_is_running(appid, &isRunning);
2045         if (ret < 0) {
2046                 _LOGE("Failed to execute app_manager_is_running[%d].\n", ret);
2047                 return ret;
2048         }
2049         _LOGE("app[%s] , running state[%d].\n", appid, isRunning);
2050
2051         if (isRunning) {
2052                 ret = app_manager_get_app_context(appid, &appCtx);
2053                 if (ret < 0) {
2054                         _LOGE("Failed to execute app_manager_get_app_context[%d].\n", ret);
2055                         return ret;
2056                 }
2057
2058                 ret = app_manager_terminate_app(appCtx);
2059                 if (ret < 0) {
2060                         _LOGE("Failed to execute app_manager_terminate_app[%d].\n", ret);
2061                         app_context_destroy(appCtx);
2062                         return ret;
2063                 }
2064
2065                 int i = 0;
2066                 for (i = 0; i < TERMINATE_RETRY_COUNT; i++) {
2067                         ret = app_manager_is_running(appid, &isRunning);
2068                         if (ret < 0) {
2069                                 _LOGE("Failed to execute app_manager_is_running[%d].\n", ret);
2070                                 app_context_destroy(appCtx);
2071                                 return ret;
2072                         }
2073
2074                         if (!isRunning) {
2075                                 _LOGD("App(%s) is terminated.\n", appid);
2076                                 break;
2077                         } else {
2078                                 _LOGD("App(%s) is not terminated yet. wait count=[%d].\n", appid, i);
2079                                 usleep(100000);
2080                         }
2081                 }
2082
2083                 ret = app_context_destroy(appCtx);
2084                 if (ret < 0) {
2085                         _LOGE("Failed to execute app_context_destroy[%d].\n", ret);
2086                         return ret;
2087                 }
2088         }
2089
2090         return ret;
2091 }
2092
2093 int __ri_change_dir(const char *dirname)
2094 {
2095         int ret = 0;
2096
2097         ret = mkdir(dirname, 0644);
2098         if (ret < 0) {
2099                 if (access(dirname, F_OK) == 0) {
2100                         _installer_util_delete_dir(dirname);
2101                         ret = mkdir(dirname, 0644);
2102                         if (ret < 0) {
2103                                 _LOGE("mkdir(%s) failed\n", dirname);
2104                                 return -1;
2105                         }
2106                 } else {
2107                         _LOGE("can not access[%s]\n", dirname);
2108                         return -1;
2109                 }
2110         }
2111
2112         ret = chdir(dirname);
2113         if (ret != 0) {
2114                 char buf[BUF_SIZE] = { 0, };
2115                 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
2116                         _LOGE("chdir(%s) failed [%s]\n", dirname, buf);
2117                 }
2118                 return -1;
2119         }
2120         return 0;
2121 }
2122
2123 int _ri_smack_reload(const char *pkgid, rpm_request_type request_type)
2124 {
2125         int ret = 0;
2126         char *op_type = NULL;
2127
2128         switch (request_type) {
2129         case INSTALL_REQ:
2130                 op_type = strdup("install");
2131                 break;
2132
2133         case UPGRADE_REQ:
2134                 op_type = strdup("update");
2135                 break;
2136
2137         case UNINSTALL_REQ:
2138                 op_type = strdup("uninstall");
2139                 break;
2140
2141         default:
2142                 break;
2143         }
2144
2145         if (op_type == NULL) {
2146                 _LOGE("@Failed to reload smack. request_type not matched[pkgid=%s, op=%s]", pkgid, op_type);
2147                 return -1;
2148         }
2149
2150         const char *smack_argv[] = { "/usr/bin/smack_reload.sh", op_type, pkgid, NULL };
2151         ret = _ri_xsystem(smack_argv);
2152         if (ret != 0) {
2153                 _LOGE("@Failed to reload smack[pkgid=%s, op=%s].", pkgid, op_type);
2154         } else {
2155                 _LOGD("#success: smack reload[pkgid=%s, op=%s]", pkgid, op_type);
2156         }
2157         if (op_type) {
2158                 free(op_type);
2159                 op_type = NULL;
2160         }
2161         return ret;
2162 }
2163
2164 int _ri_smack_reload_all(void)
2165 {
2166         int ret = 0;
2167
2168         const char *smack_argv[] = { "/usr/bin/smackload-fast", NULL };
2169         ret = _ri_xsystem(smack_argv);
2170         if (ret != 0) {
2171                 _LOGE("@Failed to reload all smack : %d", errno);
2172         } else {
2173                 _LOGD("#success: smack reload all");
2174         }
2175
2176         return ret;
2177 }
2178
2179 void __ri_remove_updated_dir(const char *pkgid)
2180 {
2181         char path_buf[BUF_SIZE] = { '\0' };
2182
2183         /* check pkgid */
2184         if (pkgid == NULL) {
2185                 _LOGE("pkgid is NULL.");
2186                 return;
2187         }
2188
2189         /* remove bin dir */
2190         snprintf(path_buf, BUF_SIZE, "%s/%s/%s", OPT_USR_APPS, pkgid, BIN_DIR_STR);
2191         if (__is_dir(path_buf)) {
2192                 _LOGE("@pkgid[%s] need to clean dir[%s]\n", pkgid, path_buf);
2193                 _installer_util_delete_dir(path_buf);
2194         }
2195
2196         /* remove res dir */
2197         memset(path_buf, '\0', BUF_SIZE);
2198         snprintf(path_buf, BUF_SIZE, "%s/%s/%s", OPT_USR_APPS, pkgid, RES_DIR_STR);
2199         if (__is_dir(path_buf)) {
2200                 _LOGE("@pkgid[%s] need to clean dir[%s]\n", pkgid, path_buf);
2201                 _installer_util_delete_dir(path_buf);
2202         }
2203
2204         /* remove shared/res dir */
2205         memset(path_buf, '\0', BUF_SIZE);
2206         snprintf(path_buf, BUF_SIZE, "%s/%s/%s", OPT_USR_APPS, pkgid, SHARED_RES_DIR_STR);
2207         if (__is_dir(path_buf)) {
2208                 _LOGE("@pkgid[%s] need to clean dir[%s]\n", pkgid, path_buf);
2209                 _installer_util_delete_dir(path_buf);
2210         }
2211 }
2212
2213 static int __metadata_func(const char *key, const char *value, void *user_data)
2214 {
2215         int ret = 0;
2216         bool isRunning = 0;
2217
2218         if (key == NULL) {
2219                 _LOGE("key is null\n");
2220                 return -1;
2221         }
2222         if (value == NULL) {
2223                 _LOGE("value is null\n");
2224                 return -1;
2225         }
2226         if (user_data == NULL) {
2227                 _LOGE("user_data is null\n");
2228                 return -1;
2229         }
2230
2231         if ((strcmp(key, "launch-on-attach") == 0) && (strcmp(value, "true") == 0)) {
2232                 _LOGE("consumer[%s] : launch-on-attach is true \n", (char *)user_data);
2233
2234                 ret = app_manager_is_running((char *)user_data, &isRunning);
2235                 if (ret < 0) {
2236                         _LOGE("Failed to execute app_manager_is_running[%s].\n", (char *)user_data);
2237                         return ret;
2238                 }
2239
2240                 if (isRunning) {
2241                         _LOGE("consumer[%s] is already launched \n", (char *)user_data);
2242                 } else {
2243                         usleep(100 * 1000);     /* 100ms sleep for infomation ready */
2244                         ret = aul_launch_app((char *)user_data, NULL);
2245                         if (ret == AUL_R_ERROR) {
2246                                 _LOGE("consumer[%s] launch fail, sleep and retry  launch_app\n", (char *)user_data);
2247                                 usleep(100 * 1000);     /* 100ms sleep for infomation ready */
2248                                 aul_launch_app((char *)user_data, NULL);
2249                         }
2250                         _LOGE("consumer[%s] is launched !!!! \n", (char *)user_data);
2251                 }
2252         }
2253         return 0;
2254 }
2255
2256 static int __ri_find_svcapp(const pkgmgrinfo_appinfo_h handle, void *user_data)
2257 {
2258         int ret = 0;
2259         char *appid = NULL;
2260         char *component_type = NULL;
2261
2262         ret = pkgmgrinfo_appinfo_get_component_type(handle, &component_type);
2263         if (ret != PMINFO_R_OK) {
2264                 _LOGE("@Failed to get component_type\n");
2265                 return -1;
2266         }
2267
2268         if (strcmp(component_type, "svcapp") == 0) {
2269                 ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
2270                 if (ret != PMINFO_R_OK) {
2271                         _LOGE("@Failed to get appid\n");
2272                         return -1;
2273                 }
2274                 _LOGE("@find consumer[%s], check metadata for launch\n", appid);
2275
2276                 ret = pkgmgrinfo_appinfo_foreach_metadata(handle, __metadata_func, (void *)appid);
2277                 if (ret != PMINFO_R_OK) {
2278                         _LOGE("@Failed to get foreach_metadata\n");
2279                         return -1;
2280                 }
2281         }
2282
2283         return 0;
2284 }
2285
2286 static void __ri_launch_consumer(const char *pkgid)
2287 {
2288         int ret = 0;
2289         pkgmgrinfo_pkginfo_h pkghandle = NULL;
2290
2291         ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
2292         if (ret < 0) {
2293                 _LOGE("@Failed to get pkginfo handle [%s]\n", pkgid);
2294                 return;
2295         }
2296
2297         ret = pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_find_svcapp, NULL);
2298         if (ret < 0) {
2299                 _LOGE("@Failed to get appinfo_get_list [%s]\n", pkgid);
2300                 return;
2301         }
2302         pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
2303 }
2304
2305 static int __child_list_cb(const pkgmgrinfo_pkginfo_h handle, void *user_data)
2306 {
2307         int ret = 0;
2308         char *pkgid = NULL;
2309
2310         ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
2311         if (ret < 0) {
2312                 _LOGE("get_pkgid failed\n");
2313                 return ret;
2314         }
2315
2316         _LOGD("@child pkgid is [%s] for uninstallation", pkgid);
2317
2318         ret = _rpm_uninstall_pkg_with_dbpath(pkgid, 0);
2319         if (ret != 0) {
2320                 _LOGE("uninstall pkg(%s) failed\n", pkgid);
2321         }
2322
2323         return ret;
2324 }
2325
2326 static void __uninstall_child_package_by_mother_pkgid(const char *pkgid)
2327 {
2328         int ret = 0;
2329         pkgmgrinfo_pkginfo_filter_h handle = NULL;
2330
2331         ret = pkgmgrinfo_pkginfo_filter_create(&handle);
2332         if (ret != 0) {
2333                 _LOGE("filter_create failed for (%s)\n", pkgid);
2334                 return;
2335         }
2336
2337         ret = pkgmgrinfo_pkginfo_filter_add_string(handle, PMINFO_PKGINFO_PROP_PACKAGE_STORECLIENT_ID, pkgid);
2338         if (ret < 0) {
2339                 _LOGE("PMINFO_PKGINFO_PROP_PACKAGE_STORECLIENT_ID add failed\n");
2340                 goto end;
2341         }
2342
2343         ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(handle, __child_list_cb, NULL);
2344         if (ret < 0) {
2345                 _LOGE("foreach_pkginfo failed\n");
2346         }
2347
2348 end:
2349         pkgmgrinfo_pkginfo_filter_destroy(handle);
2350 }
2351
2352 int _rpm_install_pkg_with_dbpath(char *pkgfilepath, char *pkgid, char *clientid)
2353 {
2354         int ret = 0;
2355         char manifest[BUF_SIZE] = { '\0' };
2356         char resultxml[BUF_SIZE] = { '\0' };
2357         char resxml[BUF_SIZE] = { '\0' };
2358         char cwd[BUF_SIZE] = { '\0' };
2359         int home_dir = 0;
2360         char *temp = NULL;
2361         char buf[BUF_SIZE] = { 0, };
2362
2363 #ifdef APP2EXT_ENABLE
2364         app2ext_handle *handle = NULL;
2365         GList *dir_list = NULL;
2366         pkgmgrinfo_install_location location = 1;
2367         int size = -1;
2368         unsigned long rpm_size = 0;
2369 #endif
2370         char *smack_label = NULL;
2371
2372         /* send event for start */
2373         _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "start", "install");
2374         _LOGD("[#]start : _rpm_install_pkg_with_dbpath");
2375
2376         /* getcwd */
2377         temp = getcwd(cwd, BUF_SIZE);
2378         if ((temp == NULL) || (cwd[0] == '\0')) {
2379                 _LOGE("@failed to get the current directory info.");
2380                 ret = RPM_INSTALLER_ERR_INTERNAL;
2381                 goto err;
2382         }
2383         _LOGD("#current working directory is %s", cwd);
2384
2385         /* change dir */
2386         ret = __ri_change_dir(TEMP_DIR);
2387         if (ret == -1) {
2388                 _LOGE("@failed to change directory.");
2389                 ret = RPM_INSTALLER_ERR_INTERNAL;
2390                 goto err;
2391         }
2392         _LOGD("#switched to %s", TEMP_DIR);
2393
2394         /* run cpio script */
2395         const char *cpio_argv[] = { CPIO_SCRIPT, pkgfilepath, NULL };
2396         ret = _ri_xsystem(cpio_argv);
2397
2398         /* get manifext.xml path */
2399         snprintf(manifest, BUF_SIZE, "%s%s/%s.xml", TEMP_DIR, OPT_SHARE_PACKAGES, pkgid);
2400         _LOGD("#manifest name is %s", manifest);
2401
2402         if (access(manifest, F_OK)) {
2403                 _LOGD("#there is no RW manifest.xml. check RO manifest.xml.");
2404
2405                 memset(manifest, '\0', sizeof(manifest));
2406                 snprintf(manifest, BUF_SIZE, "%s%s/%s.xml", TEMP_DIR, USR_SHARE_PACKAGES, pkgid);
2407                 _LOGD("#manifest name is %s", manifest);
2408
2409                 if (access(manifest, F_OK)) {
2410                         _LOGE("@can not find manifest.xml in the pkg.");
2411                         ret = RPM_INSTALLER_ERR_NO_MANIFEST;
2412                         goto err;
2413                 } else {
2414                         home_dir = 0;
2415                 }
2416
2417 #if 0
2418                 /* disable "copy ro-xml to rw-xml", because of some bug */
2419                 snprintf(srcpath, BUF_SIZE, "%s", manifest);
2420                 memset(manifest, '\0', sizeof(manifest));
2421                 snprintf(manifest, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
2422
2423                 const char *xml_update_argv[] = { CPIO_SCRIPT_UPDATE_XML, srcpath, manifest, NULL };
2424                 ret = _ri_xsystem(xml_update_argv);
2425 #endif
2426         } else {
2427                 home_dir = 1;
2428         }
2429
2430         /* send event for install_percent */
2431         _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "30");
2432
2433         /* check manifest.xml validation */
2434         ret = pkgmgr_parser_check_manifest_validation(manifest);
2435         if (ret < 0) {
2436                 _LOGE("@invalid manifest");
2437                 ret = RPM_INSTALLER_ERR_INVALID_MANIFEST;
2438                 goto err;
2439         }
2440
2441         /* check existance of res.xml for resource manager */
2442         snprintf(resxml, BUF_SIZE, "%s%s/%s/res/res.xml", TEMP_DIR, USR_APPS, pkgid);
2443         _LOGD("#path of res.xml is %s", resxml);
2444         if (access(resxml, F_OK) != 0) {
2445                 _LOGE("file not found. try other paths");
2446                 memset(resxml, '\0', sizeof(resxml));
2447                 snprintf(resxml, BUF_SIZE, "%s%s/%s/res/res.xml", TEMP_DIR, OPT_USR_APPS, pkgid);
2448                 if (access(resxml, F_OK) != 0) {
2449                         _LOGE("file not found");
2450                         memset(resxml, '\0', sizeof(resxml));
2451                 }
2452         }
2453
2454         if (resxml[0] != '\0') {
2455                 if (access(resxml, R_OK) == 0) {
2456                         /* validate it */
2457                         ret = pkgmgr_resource_parser_check_xml_validation(resxml);
2458                         if (ret < 0) {
2459                                 _LOGE("pkgmgr_resource_parser_check_xml_validation(%s) failed.", resxml);
2460                                 ret = RPM_INSTALLER_ERR_INTERNAL;
2461                                 goto err;
2462                         }
2463                 }
2464         }
2465
2466         /* chdir */
2467         ret = chdir(cwd);
2468         if (ret != 0) {
2469                 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
2470                         _LOGE("@failed to change directory(%s)(%s)", cwd, buf);
2471                 }
2472                 ret = RPM_INSTALLER_ERR_INTERNAL;
2473                 goto err;
2474         }
2475 #ifdef APP2EXT_ENABLE
2476         ret = __get_location_from_xml(manifest, &location);
2477         if (ret < 0) {
2478                 _LOGE("@Failed to get install location\n");
2479                 ret = RPM_INSTALLER_ERR_INTERNAL;
2480                 goto err;
2481         } else {
2482                 if (location == PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL) {
2483                         _LOGD("#Install: external storage location");
2484
2485                         /* Get the rpm's size from rpm header */
2486                         rpm_size = _ri_calculate_rpm_size(pkgfilepath);
2487                         if (rpm_size != 0) {
2488                                 rpm_size = rpm_size / (1024 * 1024);    /* rpm size in MB */
2489                                 _LOGD("#Rpm file(%s) size is %lu MB", pkgfilepath, rpm_size);
2490
2491                                 /* Add margin to the rpm size */
2492                                 rpm_size = rpm_size + RPM_SIZE_MARGIN(rpm_size);
2493                                 _LOGD("#Rpm file (%s) size after margin is %lu MB", pkgfilepath, rpm_size);
2494                         } else {
2495                                 _LOGE("@Failed to get size from rpm header\n");
2496                                 ret = RPM_INSTALLER_ERR_INTERNAL;
2497                                 goto err;
2498                         }
2499
2500                         /* Get the size from the manifest file. */
2501                         ret = __get_size_from_xml(manifest, &size);
2502                         if (ret != PMINFO_R_OK) {
2503                                 size = rpm_size;
2504                                 _LOGD(" #rpm size is %d MB", size);
2505                         } else {
2506                                 size = size > rpm_size ? size : rpm_size;
2507                                 _LOGD("#rpm size is %d MB", size);
2508                         }
2509                 }
2510         }
2511
2512         if ((location == PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL) && size > 0) {
2513                 handle = app2ext_init(APP2EXT_SD_CARD);
2514                 if (handle == NULL) {
2515                         _LOGE("@app2ext init failed\n");
2516                         ret = RPM_INSTALLER_ERR_INTERNAL;
2517                         goto err;
2518                 }
2519                 if ((&(handle->interface) != NULL) && (handle->interface.pre_install != NULL)
2520                         && (handle->interface.post_install != NULL)) {
2521                         dir_list = __rpm_populate_dir_list();
2522                         if (dir_list == NULL) {
2523                                 _LOGE("@ \nError in populating the directory list\n");
2524                                 app2ext_deinit(handle);
2525                                 ret = RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
2526                                 goto err;
2527                         }
2528                         ret = handle->interface.pre_install(gpkgname, dir_list, size);
2529                         if (ret == APP2EXT_ERROR_MMC_STATUS) {
2530                                 _LOGE("@app2xt MMC is not here, go internal\n");
2531                         } else if (ret == APP2EXT_SUCCESS) {
2532                                 _LOGE("@pre_install done, go internal\n");
2533                         } else {
2534                                 _LOGE("@app2xt pre install API failed (%d)\n", ret);
2535                                 __rpm_clear_dir_list(dir_list);
2536                                 handle->interface.post_install(gpkgname, APP2EXT_STATUS_FAILED);
2537                                 app2ext_deinit(handle);
2538                                 ret = RPM_INSTALLER_ERR_INTERNAL;
2539                                 goto err;
2540                         }
2541                 }
2542         }
2543 #endif
2544
2545         /* run script */
2546         if (home_dir == 0) {
2547 #if 0
2548                 /* disable "INSTALL_SCRIPT_WITH_DBPATH_RO", because of some bug */
2549                 const char *argv[] = { INSTALL_SCRIPT_WITH_DBPATH_RO, pkgfilepath, NULL };
2550                 ret = _ri_xsystem(argv);
2551 #endif
2552                 const char *argv[] = { INSTALL_SCRIPT, pkgfilepath, NULL };
2553                 ret = _ri_xsystem(argv);
2554         } else {
2555                 const char *argv[] = { INSTALL_SCRIPT_WITH_DBPATH_RW, pkgfilepath, NULL };
2556                 ret = _ri_xsystem(argv);
2557         }
2558         if (ret != 0) {
2559                 _LOGE("@failed to install the pkg(%d).", ret);
2560 #ifdef APP2EXT_ENABLE
2561                 if ((handle != NULL) && (handle->interface.post_install != NULL)) {
2562                         __rpm_clear_dir_list(dir_list);
2563                         handle->interface.post_install(gpkgname, APP2EXT_STATUS_FAILED);
2564                         app2ext_deinit(handle);
2565                 }
2566 #endif
2567                 goto err;
2568         }
2569         _LOGD("#install success.");
2570
2571         /* check for signature and certificate */
2572         ret = _ri_verify_signatures(TEMP_DIR, pkgid, true);
2573         if (ret < 0) {
2574                 _LOGE("@signature and certificate failed(%s).", pkgid);
2575                 ret = RPM_INSTALLER_ERR_SIG_INVALID;
2576                 goto err;
2577         }
2578         _LOGD("#_ri_verify_signatures success.");
2579
2580         /* write the storeclient-id to manifest.xml */
2581         if (clientid != NULL) {
2582                 if (home_dir == 0) {
2583                         snprintf(resultxml, BUF_SIZE, "%s/%s.xml", USR_SHARE_PACKAGES, pkgid);
2584                 } else {
2585                         snprintf(resultxml, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
2586                 }
2587
2588                 const char *convert_argv[] = { RPM_UPDATE_XML, manifest, clientid, resultxml, NULL };
2589                 ret = _ri_xsystem(convert_argv);
2590                 if (ret != 0) {
2591                         _LOGE("@Failed to convert the manifest.xml");
2592                         goto err;
2593                 }
2594
2595                 _LOGD("#client id[%s], input manifest:[%s], dest manifest:[%s]", clientid, manifest, resultxml);
2596         }
2597
2598         /* send event for install_percent */
2599         _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "60");
2600
2601         /* Parse the manifest to get install location and size.
2602            If installation fails, remove manifest info from DB */
2603         if (clientid != NULL) {
2604                 ret = pkgmgr_parser_parse_manifest_for_installation(resultxml, NULL);
2605         } else {
2606                 ret = pkgmgr_parser_parse_manifest_for_installation(manifest, NULL);
2607         }
2608         if (ret < 0) {
2609                 _LOGE("@failed to parse the manifest.");
2610                 ret = RPM_INSTALLER_ERR_INTERNAL;
2611                 goto err;
2612         }
2613         _LOGD("#manifest parsing success");
2614
2615 #ifdef APP2EXT_ENABLE
2616         if ((handle != NULL) && (handle->interface.post_install != NULL)) {
2617                 __rpm_clear_dir_list(dir_list);
2618                 handle->interface.post_install(gpkgname, APP2EXT_STATUS_SUCCESS);
2619                 app2ext_deinit(handle);
2620         }
2621 #endif
2622         /* register cert info */
2623         _ri_register_cert(pkgid);
2624
2625         /* search_ug_app */
2626         _coretpk_installer_search_ui_gadget(pkgid);
2627
2628         /* apply smack to shared dir */
2629         ret = __get_smack_label_from_db(pkgid, &smack_label);
2630         _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
2631
2632         __rpm_apply_smack(pkgid, 1, smack_label);
2633
2634         /* apply smack by privilege */
2635         ret = _ri_apply_privilege(pkgid, 0, smack_label);
2636         if (ret != 0) {
2637                 _LOGE("@failed to apply permission(%d).", ret);
2638         }
2639         _LOGD("#permission applying success.");
2640
2641         /* reload smack */
2642         ret = _ri_smack_reload_all();
2643         if (ret != 0) {
2644                 _LOGD("@failed to reload_all the smack.");
2645         }
2646
2647         /* send event for install_percent */
2648         _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "100");
2649
2650         ret = RPM_INSTALLER_SUCCESS;
2651
2652 err:
2653         _installer_util_delete_dir(TEMP_DIR);
2654         _installer_util_delete_dir(TEMP_DBPATH);
2655
2656         if (ret == RPM_INSTALLER_SUCCESS) {
2657                 _LOGD("[#]end : _rpm_install_pkg_with_dbpath");
2658                 __ri_launch_consumer(pkgid);
2659                 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "end", "ok");
2660                 _ri_stat_cb(pkgid, "end", "ok");
2661         } else {
2662                 _LOGE("[@]end : _rpm_install_pkg_with_dbpath");
2663                 /* remove db info */
2664                 ret = _coretpk_installer_remove_db_info(pkgid);
2665                 if (ret < 0) {
2666                         _LOGE("_coretpk_installer_remove_db_info is failed.");
2667                 }
2668
2669                 char *errstr = NULL;
2670                 _ri_error_no_to_string(ret, &errstr);
2671                 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "error", errstr);
2672                 _ri_stat_cb(pkgid, "error", errstr);
2673                 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "end", "fail");
2674                 sleep(2);
2675                 _ri_stat_cb(pkgid, "end", "fail");
2676                 _LOGE("install failed with err(%d) (%s)\n", ret, errstr);
2677         }
2678
2679         FREE_AND_NULL(smack_label);
2680
2681         return ret;
2682 }
2683
2684 int _rpm_upgrade_pkg_with_dbpath(char *pkgfilepath, char *pkgid)
2685 {
2686         int ret = 0;
2687         char manifest[BUF_SIZE] = { '\0' };
2688         char cwd[BUF_SIZE] = { '\0' };
2689         int home_dir = 0;
2690         pkgmgrinfo_pkginfo_h pkghandle;
2691         char *temp = NULL;
2692 #ifdef APP2EXT_ENABLE
2693         app2ext_handle *handle = NULL;
2694         GList *dir_list = NULL;
2695         pkgmgrinfo_installed_storage location = 1;
2696         int size = -1;
2697         unsigned long rpm_size = 0;
2698 #endif
2699         char *smack_label = NULL;
2700         char resxml[BUF_SIZE] = { '\0' };
2701         char buf[BUF_SIZE] = { 0, };
2702
2703         _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "start", "update");
2704         _LOGD("[#]start : _rpm_upgrade_pkg_with_dbpath");
2705
2706         /* terminate running app */
2707         ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
2708         if (ret < 0) {
2709                 _LOGE("@failed to get pkginfo handle");
2710                 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
2711                 goto err;
2712         }
2713         pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, NULL);
2714         pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
2715
2716         /* getcwd */
2717         temp = getcwd(cwd, BUF_SIZE);
2718         if ((temp == NULL) || (cwd[0] == '\0')) {
2719                 _LOGE("@getcwd() failed.");
2720                 ret = RPM_INSTALLER_ERR_INTERNAL;
2721                 goto err;
2722         }
2723         _LOGD("#current working directory is %s.", cwd);
2724
2725         /* change dir */
2726         ret = __ri_change_dir(TEMP_DIR);
2727         if (ret == -1) {
2728                 _LOGE("@change dir failed.");
2729                 ret = RPM_INSTALLER_ERR_INTERNAL;
2730                 goto err;
2731         }
2732         _LOGD("#switched to %s", TEMP_DIR);
2733
2734         /* run cpio script */
2735         const char *cpio_argv[] = { CPIO_SCRIPT, pkgfilepath, NULL };
2736         ret = _ri_xsystem(cpio_argv);
2737
2738         /* get manifext.xml path */
2739         snprintf(manifest, BUF_SIZE, "%s%s/%s.xml", TEMP_DIR, OPT_SHARE_PACKAGES, pkgid);
2740         _LOGD("#manifest name is %s.", manifest);
2741
2742         if (access(manifest, F_OK)) {
2743                 _LOGD("#there is no RW manifest.xml. check RO manifest.xml.");
2744
2745                 memset(manifest, '\0', sizeof(manifest));
2746                 snprintf(manifest, BUF_SIZE, "%s%s/%s.xml", TEMP_DIR, USR_SHARE_PACKAGES, pkgid);
2747                 _LOGD("#manifest name is %s.", manifest);
2748
2749                 if (access(manifest, F_OK)) {
2750                         _LOGE("@can not find manifest.xml in the pkg.");
2751                         ret = RPM_INSTALLER_ERR_NO_MANIFEST;
2752                         goto err;
2753                 } else {
2754                         home_dir = 0;
2755                 }
2756
2757 #if 0
2758                 /* disable "copy ro-xml to rw-xml", because of some bug */
2759                 snprintf(srcpath, BUF_SIZE, "%s", manifest);
2760                 memset(manifest, '\0', sizeof(manifest));
2761                 snprintf(manifest, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
2762
2763                 const char *xml_update_argv[] = { CPIO_SCRIPT_UPDATE_XML, srcpath, manifest, NULL };
2764                 ret = _ri_xsystem(xml_update_argv);
2765 #endif
2766         } else {
2767                 home_dir = 1;
2768         }
2769
2770         /* check existance of res.xml for resource manager */
2771         snprintf(resxml, BUF_SIZE, "%s%s/%s/res/res.xml", TEMP_DIR, USR_APPS, pkgid);
2772         _LOGD("#path of res.xml is %s", resxml);
2773         if (access(resxml, F_OK) != 0) {
2774                 _LOGE("file not found. try other paths");
2775                 memset(resxml, '\0', sizeof(resxml));
2776                 snprintf(resxml, BUF_SIZE, "%s%s/%s/res/res.xml", TEMP_DIR, OPT_USR_APPS, pkgid);
2777                 if (access(resxml, F_OK) != 0) {
2778                         _LOGE("file not found");
2779                         memset(resxml, '\0', sizeof(resxml));
2780                 }
2781         }
2782
2783         if (resxml[0] != '\0') {
2784                 if (access(resxml, R_OK) == 0) {
2785                         /* validate it */
2786                         ret = pkgmgr_resource_parser_check_xml_validation(resxml);
2787                         if (ret < 0) {
2788                                 _LOGE("pkgmgr_resource_parser_check_xml_validation(%s) failed.", resxml);
2789                                 ret = RPM_INSTALLER_ERR_INTERNAL;
2790                                 goto err;
2791                         }
2792                 }
2793         }
2794
2795         /* send event for install_percent */
2796         _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "30");
2797
2798         /* check manifest.xml validation */
2799         ret = pkgmgr_parser_check_manifest_validation(manifest);
2800         if (ret < 0) {
2801                 _LOGE("@invalid manifest");
2802                 ret = RPM_INSTALLER_ERR_INVALID_MANIFEST;
2803                 goto err;
2804         }
2805
2806         /* check for signature and certificate */
2807         ret = _ri_verify_signatures(TEMP_DIR, pkgid, true);
2808         if (ret < 0) {
2809                 _LOGE("@signature and certificate failed(%s).", pkgid);
2810                 ret = RPM_INSTALLER_ERR_SIG_INVALID;
2811                 goto err;
2812         }
2813         _LOGD("#_ri_verify_signatures success.");
2814
2815         /* chdir */
2816         ret = chdir(cwd);
2817         if (ret != 0) {
2818                 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
2819                         _LOGE("@chdir(%s) failed(%s).", cwd, buf);
2820                 }
2821                 ret = RPM_INSTALLER_ERR_INTERNAL;
2822                 goto err;
2823         }
2824
2825         /* remove dir for clean */
2826         __ri_remove_updated_dir(pkgid);
2827
2828         _LOGD("#Preserve the smack file");
2829         /* Preserve the smack rule file */
2830         ret = __ri_copy_smack_rule_file(UPGRADE_REQ, pkgid, 0);
2831         if (ret != RPM_INSTALLER_SUCCESS)
2832                 goto err;
2833
2834 #ifdef APP2EXT_ENABLE
2835         ret = pkgmgrinfo_pkginfo_get_pkginfo(gpkgname, &pkghandle);
2836         if (ret < 0) {
2837                 _LOGE("Failed to get pkginfo handle\n");
2838                 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
2839                 goto err;
2840         }
2841
2842         ret = pkgmgrinfo_pkginfo_get_installed_storage(pkghandle, &location);
2843         if (ret < 0) {
2844                 _LOGE("Failed to get install location\n");
2845                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
2846                 ret = RPM_INSTALLER_ERR_INTERNAL;
2847                 goto err;
2848         }
2849
2850         if (location == PMINFO_EXTERNAL_STORAGE) {
2851                 /* Get the rpm's size from rpm header */
2852                 rpm_size = _ri_calculate_rpm_size(pkgfilepath);
2853                 if (rpm_size == 0) {
2854                         _LOGE("@Failed to get size from rpm header\n");
2855                         ret = RPM_INSTALLER_ERR_INTERNAL;
2856                         goto err;
2857                 }
2858                 rpm_size = rpm_size / (1024 * 1024);    /* rpm size in MB */
2859                 _LOGD("#Rpm file(%s) size is %lu MB", pkgfilepath, rpm_size);
2860
2861                 /* Add margin to the rpm size */
2862                 rpm_size = rpm_size + RPM_SIZE_MARGIN(rpm_size);
2863                 _LOGD("#Rpm file (%s) size after margin is %lu MB", pkgfilepath, rpm_size);
2864
2865                 /* Get the size from the manifest file. */
2866                 ret = __get_size_from_xml(manifest, &size);
2867                 if (ret != PMINFO_R_OK) {
2868                         size = rpm_size;
2869                         _LOGD(" #rpm size is %d", size);
2870                 } else {
2871                         size = size > rpm_size ? size : rpm_size;
2872                         _LOGD("#rpm size is %d", size);
2873                 }
2874         }
2875
2876         pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
2877
2878         if ((location == PMINFO_EXTERNAL_STORAGE) && size > 0) {
2879                 handle = app2ext_init(APP2EXT_SD_CARD);
2880                 if (handle == NULL) {
2881                         _LOGE("app2ext init failed\n");
2882                         ret = RPM_INSTALLER_ERR_INTERNAL;
2883                         goto err;
2884                 }
2885
2886                 if ((&(handle->interface) != NULL) && (handle->interface.pre_upgrade != NULL)
2887                         && (handle->interface.post_upgrade != NULL)) {
2888                         dir_list = __rpm_populate_dir_list();
2889                         if (dir_list == NULL) {
2890                                 _LOGE("\nError in populating the directory list\n");
2891                                 ret = RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
2892                                 app2ext_deinit(handle);
2893                                 goto err;
2894                         }
2895                         ret = handle->interface.pre_upgrade(gpkgname, dir_list, size);
2896                         if (ret == APP2EXT_ERROR_MMC_STATUS) {
2897                                 _LOGE("app2xt MMC is not here, go internal (%d)\n", ret);
2898                         } else if (ret == APP2EXT_SUCCESS) {
2899                                 _LOGE("pre upgrade done, go internal");
2900                         } else {
2901                                 _LOGE("app2xt pre upgrade API failed (%d)\n", ret);
2902                                 __rpm_clear_dir_list(dir_list);
2903                                 handle->interface.post_upgrade(gpkgname, APP2EXT_STATUS_FAILED);
2904                                 ret = RPM_INSTALLER_ERR_INTERNAL;
2905                                 app2ext_deinit(handle);
2906                                 goto err;
2907                         }
2908                 }
2909         }
2910 #endif
2911
2912         /* run script */
2913         if (home_dir == 0) {
2914 #if 0
2915                 /* disable "UPGRADE_SCRIPT_WITH_DBPATH_RO", because of some bug */
2916                 const char *argv[] = { UPGRADE_SCRIPT_WITH_DBPATH_RO, pkgfilepath, NULL };
2917                 ret = _ri_xsystem(argv);
2918 #endif
2919                 const char *argv[] = { UPGRADE_SCRIPT, pkgfilepath, NULL };
2920                 ret = _ri_xsystem(argv);
2921         } else {
2922                 const char *argv[] = { UPGRADE_SCRIPT_WITH_DBPATH_RW, pkgfilepath, NULL };
2923                 ret = _ri_xsystem(argv);
2924         }
2925         if (ret != 0) {
2926                 _LOGE("@upgrade complete with error(%d)", ret);
2927 #ifdef APP2EXT_ENABLE
2928                 if ((handle != NULL) && (handle->interface.post_upgrade != NULL)) {
2929                         __rpm_clear_dir_list(dir_list);
2930                         handle->interface.post_upgrade(gpkgname, APP2EXT_STATUS_FAILED);
2931                         app2ext_deinit(handle);
2932                 }
2933 #endif
2934                 goto err;
2935         }
2936         _LOGD("#upgrade script success.");
2937
2938         /* send event for install_percent */
2939         _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "60");
2940
2941         /* Parse the manifest to get install location and size.
2942            If fails, remove manifest info from DB. */
2943         ret = pkgmgr_parser_parse_manifest_for_upgrade(manifest, NULL);
2944         if (ret < 0) {
2945                 _LOGE("@parsing manifest failed.");
2946                 ret = RPM_INSTALLER_ERR_INTERNAL;
2947                 goto err;
2948         }
2949         _LOGD("#parsing manifest success.");
2950
2951         /* unregister cert info */
2952         _ri_unregister_cert(pkgid);
2953
2954         /* register cert info */
2955         _ri_register_cert(pkgid);
2956
2957 #ifdef APP2EXT_ENABLE
2958         if ((handle != NULL) && (handle->interface.post_upgrade != NULL)) {
2959                 __rpm_clear_dir_list(dir_list);
2960                 handle->interface.post_upgrade(gpkgname, APP2EXT_STATUS_SUCCESS);
2961                 app2ext_deinit(handle);
2962         }
2963 #endif
2964
2965         /* search_ug_app */
2966         _coretpk_installer_search_ui_gadget(pkgid);
2967
2968         /* apply smack to shared dir */
2969         ret = __get_smack_label_from_db(pkgid, &smack_label);
2970         _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
2971
2972         __rpm_apply_smack(pkgid, 1, smack_label);
2973
2974         /* apply smack by privilege */
2975         ret = _ri_apply_privilege(pkgid, 0, smack_label);
2976         if (ret != 0) {
2977                 _LOGE("@apply perm failed with err(%d)", ret);
2978         }
2979         _LOGD("#apply perm success.");
2980
2981         /* reload smack */
2982         ret = _ri_smack_reload_all();
2983         if (ret != 0) {
2984                 _LOGD("_ri_smack_reload_all failed.");
2985         }
2986
2987         /* send event for install_percent */
2988         _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "100");
2989
2990         ret = RPM_INSTALLER_SUCCESS;
2991
2992 err:
2993         _installer_util_delete_dir(TEMP_DIR);
2994         _installer_util_delete_dir(TEMP_DBPATH);
2995
2996         if (ret == RPM_INSTALLER_SUCCESS) {
2997                 _LOGD("[#]end : _rpm_upgrade_pkg_with_dbpath");
2998                 __ri_launch_consumer(pkgid);
2999                 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "end", "ok");
3000                 _ri_stat_cb(pkgid, "end", "ok");
3001         } else {
3002                 _LOGE("[@]end : _rpm_upgrade_pkg_with_dbpath");
3003                 char *errstr = NULL;
3004                 _ri_error_no_to_string(ret, &errstr);
3005                 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "error", errstr);
3006                 _ri_stat_cb(pkgid, "error", errstr);
3007                 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "end", "fail");
3008                 sleep(2);
3009                 _ri_stat_cb(pkgid, "end", "fail");
3010                 _LOGE("install failed with err(%d) (%s)\n", ret, errstr);
3011         }
3012
3013         FREE_AND_NULL(smack_label);
3014
3015         return ret;
3016 }
3017
3018 int _rpm_uninstall_pkg_with_dbpath(const char *pkgid, bool is_system)
3019 {
3020         if (pkgid == NULL) {
3021                 _LOGE("pkgid is NULL.");
3022                 return RPM_INSTALLER_ERR_WRONG_PARAM;
3023         }
3024
3025         int ret = 0;
3026         int tmp = 0;
3027         char buff[BUF_SIZE] = { '\0' };
3028         char extpath[BUF_SIZE] = { '\0' };
3029         char tizen_manifest[BUF_SIZE] = { '\0' };
3030         pkgmgrinfo_pkginfo_h pkghandle = NULL;
3031         bool mother_package = false;
3032         bool coretpk = false;
3033         GList *appid_list = NULL;
3034
3035 #ifdef APP2EXT_ENABLE
3036         app2ext_handle *handle = NULL;
3037         pkgmgrinfo_installed_storage location = 1;
3038 #endif
3039         char *smack_label = NULL;
3040
3041         _LOGD("pkgid=[%s], is_system=[%d]", pkgid, is_system);
3042
3043         snprintf(tizen_manifest, BUF_SIZE, "%s/%s/tizen-manifest.xml", OPT_USR_APPS, pkgid);
3044         if (access(tizen_manifest, R_OK) == 0) {
3045                 coretpk = true;
3046                 _LOGD("[%s] is existing.", tizen_manifest);
3047         }
3048
3049         /* send start event */
3050         if (is_system) {
3051                 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "start", "update");
3052         } else {
3053                 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "start", "uninstall");
3054         }
3055
3056         /* terminate running app */
3057         ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
3058         if (ret < 0) {
3059                 _LOGE("pkgmgrinfo_pkginfo_get_pkginfo(%s) failed.", pkgid);
3060                 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3061                 goto end;
3062         }
3063         pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, &appid_list);
3064
3065         while (appid_list != NULL) {
3066                 _ri_broadcast_app_uninstall_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, (char *)appid_list->data);
3067
3068                 if (appid_list->next == NULL)
3069                         break;
3070                 else
3071                         appid_list = g_list_next(appid_list);
3072         }
3073
3074         /* If package is mother package, then uninstall child package */
3075         pkgmgrinfo_pkginfo_is_mother_package(pkghandle, &mother_package);
3076         if (mother_package == true) {
3077                 _LOGD("[%s] is mother package", pkgid);
3078                 __uninstall_child_package_by_mother_pkgid(pkgid);
3079         }
3080         pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3081
3082         ret = __get_smack_label_from_db(pkgid, &smack_label);
3083         _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
3084
3085         /* del root path dir */
3086         snprintf(buff, BUF_SIZE, "%s/%s", OPT_USR_APPS, pkgid);
3087         if (__is_dir(buff)) {
3088                 _installer_util_delete_dir(buff);
3089         }
3090
3091         /* del root path dir for ext */
3092         snprintf(extpath, BUF_SIZE, "%s/%s", OPT_STORAGE_SDCARD_APP_ROOT, pkgid);
3093         if (__is_dir(extpath)) {
3094                 _installer_util_delete_dir(extpath);
3095         }
3096
3097         /* del manifest */
3098         memset(buff, '\0', BUF_SIZE);
3099         snprintf(buff, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
3100         (void)remove(buff);
3101
3102         /* check system pkg, if pkg is system pkg, need to update xml on USR_SHARE_PACKAGES */
3103         if (is_system) {
3104                 memset(buff, '\0', BUF_SIZE);
3105                 snprintf(buff, BUF_SIZE, "%s/%s.xml", USR_SHARE_PACKAGES, pkgid);
3106                 _LOGE("manifest for upgrade, path=[%s]", buff);
3107
3108                 ret = pkgmgr_parser_parse_manifest_for_upgrade(buff, NULL);
3109                 if (ret < 0) {
3110                         _LOGE("parsing manifest failed.");
3111                 }
3112                 goto end;
3113         } else {
3114 #ifdef APP2EXT_ENABLE
3115                 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
3116                 if (ret < 0) {
3117                         _LOGE("failed to get pkginfo handle");
3118                         ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3119                         goto end;
3120                 }
3121                 ret = pkgmgrinfo_pkginfo_get_installed_storage(pkghandle, &location);
3122                 if (ret < 0) {
3123                         _LOGE("failed to get install location\n");
3124                         pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3125                         ret = RPM_INSTALLER_ERR_INTERNAL;
3126                         goto end;
3127                 }
3128                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3129
3130                 if (location == PMINFO_EXTERNAL_STORAGE) {
3131                         handle = app2ext_init(APP2EXT_SD_CARD);
3132                         if (handle == NULL) {
3133                                 _LOGE("app2ext init failed\n");
3134                                 ret = RPM_INSTALLER_ERR_INTERNAL;
3135                                 goto end;
3136                         }
3137                         if ((&(handle->interface) != NULL) && (handle->interface.pre_uninstall != NULL) &&
3138                                 (handle->interface.post_uninstall != NULL) &&
3139                                 (handle->interface.disable != NULL)) {
3140                                 ret = handle->interface.disable(pkgid);
3141                                 if (ret != APP2EXT_SUCCESS) {
3142                                         _LOGE("Unmount ret[%d]", ret);
3143                                 }
3144                                 ret = app2ext_get_app_location(pkgid);
3145                                 if (ret == APP2EXT_INTERNAL_MEM) {
3146                                         _LOGE("app2xt APP is not in MMC, go internal (%d)\n", ret);
3147                                 } else {
3148                                         ret = handle->interface.pre_uninstall(pkgid);
3149                                         if (ret == APP2EXT_ERROR_MMC_STATUS) {
3150                                                 _LOGE("app2xt MMC is not here, go internal (%d)\n", ret);
3151                                         } else if (ret == APP2EXT_SUCCESS) {
3152                                                 _LOGE("pre uninstall done, go to internal");
3153                                         } else {
3154                                                 _LOGE("app2xt pre uninstall API failed (%d)\n", ret);
3155                                                 handle->interface.post_uninstall(pkgid);
3156                                                 app2ext_deinit(handle);
3157                                                 ret = RPM_INSTALLER_ERR_INTERNAL;
3158                                                 goto end;
3159                                         }
3160                                 }
3161                         }
3162                 }
3163 #endif
3164
3165                 /* del db info */
3166                 ret = pkgmgr_parser_parse_manifest_for_uninstallation(pkgid, NULL);
3167                 if (ret < 0) {
3168                         _LOGE("pkgmgr_parser_parse_manifest_for_uninstallation() failed, pkgid=[%s]", pkgid);
3169                 }
3170
3171 #ifdef APP2EXT_ENABLE
3172                 if ((handle != NULL) && (handle->interface.post_uninstall != NULL)) {
3173                         handle->interface.post_uninstall(pkgid);
3174                         app2ext_deinit(handle);
3175                 }
3176 #endif
3177         }
3178
3179         /* execute privilege APIs */
3180         _ri_privilege_revoke_permissions(smack_label);
3181         _ri_privilege_unregister_package(smack_label);
3182
3183         /* Unregister cert info */
3184         _ri_unregister_cert(pkgid);
3185
3186         ret = RPM_INSTALLER_SUCCESS;
3187
3188 end:
3189         /* Free appid list */
3190         appid_list = g_list_first(appid_list);
3191         while (appid_list != NULL) {
3192                 if (appid_list->data != NULL) {
3193                         free(appid_list->data);
3194                 }
3195
3196                 if (appid_list->next == NULL)
3197                         break;
3198                 else
3199                         appid_list = g_list_next(appid_list);
3200         }
3201         g_list_free(appid_list);
3202
3203         /* Restore the old smack file */
3204         if (coretpk == false) {
3205                 tmp = __ri_copy_smack_rule_file(UNINSTALL_REQ, pkgid, is_system);
3206                 if (tmp != RPM_INSTALLER_SUCCESS) {
3207                         _LOGD("smack restore failed");
3208                         ret = tmp;
3209                 } else {
3210                         /*reload smack */
3211                         tmp = _ri_smack_reload_all();
3212                         if (tmp != 0) {
3213                                 _LOGD("_ri_smack_reload_all failed.");
3214                                 ret = tmp;
3215                         }
3216                 }
3217         }
3218
3219         if (ret != 0) {
3220                 _LOGE("failed, ret=[%d]", ret);
3221                 char *errstr = NULL;
3222                 _ri_error_no_to_string(ret, &errstr);
3223                 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "error", errstr);
3224                 _ri_stat_cb(pkgid, "error", errstr);
3225                 sleep(2);
3226                 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "end", "fail");
3227                 _ri_stat_cb(pkgid, "end", "fail");
3228                 _LOGE("remove failed with err(%d) (%s)\n", ret, errstr);
3229         } else {
3230                 _LOGE("success");
3231                 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "end", "ok");
3232                 _ri_stat_cb(pkgid, "end", "ok");
3233         }
3234
3235         FREE_AND_NULL(smack_label);
3236
3237         return ret;
3238 }
3239
3240 int _rpm_uninstall_pkg(char *pkgid)
3241 {
3242         int ret = 0;
3243         bool is_update = 0;
3244         bool is_system = 0;
3245         bool is_removable = 0;
3246         pkgmgrinfo_install_location location = 1;
3247 #ifdef APP2EXT_ENABLE
3248         app2ext_handle *handle = NULL;
3249 #endif
3250 #ifdef PRE_CHECK_FOR_MANIFEST
3251         char *manifest = NULL;
3252         int err = 0;
3253 #endif
3254         char *smack_label = NULL;
3255
3256         pkgmgrinfo_pkginfo_h pkghandle;
3257         const char *argv[] = { UNINSTALL_SCRIPT, pkgid, NULL };
3258
3259         _LOGD("start : _rpm_uninstall_pkg\n");
3260
3261         ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
3262         if (ret < 0) {
3263                 _LOGE("Failed to get pkginfo handle\n");
3264                 return RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3265         }
3266         /* terminate running app */
3267         pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, NULL);
3268
3269         ret = pkgmgrinfo_pkginfo_is_system(pkghandle, &is_system);
3270         if (ret < 0) {
3271                 _LOGE("pkgmgrinfo_pkginfo_is_system failed.\n");
3272                 return RPM_INSTALLER_ERR_INTERNAL;
3273         }
3274         if (is_system) {
3275                 ret = pkgmgrinfo_pkginfo_is_update(pkghandle, &is_update);
3276                 if (ret < 0) {
3277                         _LOGE("pkgmgrinfo_pkginfo_is_system failed.\n");
3278                         return RPM_INSTALLER_ERR_INTERNAL;
3279                 }
3280                 if (is_update) {
3281                         pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3282                         /* updated and system pkg need to "remove-update" */
3283                         _LOGD("Remove Update[%s]", pkgid);
3284                         ret = _rpm_uninstall_pkg_with_dbpath(pkgid, 1);
3285                         if (ret < 0) {
3286                                 _LOGE("uninstall_pkg_with_dbpath for system, is_update fail\n");
3287                         }
3288                         return 0;
3289                 }
3290         } else {
3291                 pkgmgrinfo_pkginfo_is_removable(pkghandle, &is_removable);
3292                 if (is_removable) {
3293                         /* non-system and can be removable,  it should be deleted */
3294                         _LOGD("Delete Package [%s]", pkgid);
3295                         pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3296                         ret = _rpm_uninstall_pkg_with_dbpath(pkgid, 0);
3297                         if (ret < 0) {
3298                                 _LOGE("uninstall_pkg_with_dbpath for non-system, is_remove fail\n");
3299                         }
3300                         return 0;
3301                 }
3302         }
3303
3304         _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "start", "uninstall");
3305
3306 #ifdef APP2EXT_ENABLE
3307         ret = pkgmgrinfo_pkginfo_get_install_location(pkghandle, &location);
3308         if (ret < 0) {
3309                 _LOGE("Failed to get install location\n");
3310                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3311                 return RPM_INSTALLER_ERR_INTERNAL;
3312         }
3313
3314         pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, NULL);
3315
3316         pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3317         if (location == PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL) {
3318                 handle = app2ext_init(APP2EXT_SD_CARD);
3319                 if (handle == NULL) {
3320                         _LOGE("app2ext init failed\n");
3321                         return RPM_INSTALLER_ERR_INTERNAL;
3322                 }
3323                 if ((&(handle->interface) != NULL) && (handle->interface.pre_uninstall != NULL) &&
3324                         (handle->interface.post_uninstall != NULL)) {
3325                         ret = app2ext_get_app_location(pkgid);
3326                         if (ret == APP2EXT_INTERNAL_MEM) {
3327                                 _LOGE("app2xt APP is not in MMC, go internal (%d)\n", ret);
3328                         } else {
3329                                 ret = handle->interface.pre_uninstall(pkgid);
3330                                 if (ret == APP2EXT_ERROR_MMC_STATUS || ret == APP2EXT_SUCCESS) {
3331                                         _LOGE("app2xt MMC is not here, go internal (%d)\n", ret);
3332                                 } else {
3333                                         _LOGE("app2xt pre uninstall API failed (%d)\n", ret);
3334                                         handle->interface.post_uninstall(pkgid);
3335                                         app2ext_deinit(handle);
3336                                         return RPM_INSTALLER_ERR_INTERNAL;
3337                                 }
3338                         }
3339                 }
3340         }
3341 #endif
3342
3343         ret = __get_smack_label_from_db(pkgid, &smack_label);
3344         _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
3345
3346 #ifdef PRE_CHECK_FOR_MANIFEST
3347         /* Manifest info should be removed first because after installation manifest
3348            file is uninstalled. If uninstallation fails, we need to re-insert manifest info for consistency */
3349         manifest = pkgmgr_parser_get_manifest_file(pkgid);
3350         if (manifest == NULL) {
3351                 _LOGE("manifest name is NULL\n");
3352                 app2ext_deinit(handle);
3353                 FREE_AND_NULL(smack_label);
3354                 return RPM_INSTALLER_ERR_NO_MANIFEST;
3355         }
3356         _LOGD("manifest name is %s\n", manifest);
3357         ret = pkgmgr_parser_parse_manifest_for_uninstallation(manifest, NULL);
3358         if (ret < 0) {
3359                 _LOGE("pkgmgr_parser_parse_manifest_for_uninstallation failed.\n");
3360         }
3361 #endif
3362
3363         ret = _rpm_xsystem(argv);
3364         if (ret != 0) {
3365                 _LOGE("uninstall failed with error(%d)\n", ret);
3366 #ifdef PRE_CHECK_FOR_MANIFEST
3367                 err = pkgmgr_parser_parse_manifest_for_installation(manifest, NULL);
3368                 if (err < 0) {
3369                         _LOGE("Parsing Manifest Failed\n");
3370                 }
3371
3372                 FREE_AND_NULL(manifest);
3373 #endif
3374 #ifdef APP2EXT_ENABLE
3375                 if ((handle != NULL) && (handle->interface.post_uninstall != NULL)) {
3376                         handle->interface.post_uninstall(pkgid);
3377                         app2ext_deinit(handle);
3378                 }
3379 #endif
3380
3381                 FREE_AND_NULL(smack_label);
3382
3383                 return ret;
3384         }
3385 #ifdef APP2EXT_ENABLE
3386         if ((handle != NULL) && (handle->interface.post_uninstall != NULL)) {
3387                 handle->interface.post_uninstall(pkgid);
3388                 app2ext_deinit(handle);
3389         }
3390 #endif
3391
3392         /* execute privilege APIs */
3393         _ri_privilege_revoke_permissions(smack_label);
3394         _ri_privilege_unregister_package(smack_label);
3395
3396         /* Unregister cert info */
3397         _ri_unregister_cert(gpkgname);
3398
3399         FREE_AND_NULL(manifest);
3400         FREE_AND_NULL(smack_label);
3401
3402         _LOGD("end : _rpm_uninstall_pkg(%d)\n", ret);
3403
3404         return ret;
3405 }
3406
3407 int _rpm_install_corexml(const char *pkgfilepath, char *pkgid)
3408 {
3409         int ret = 0;
3410
3411         /* validate signature and certifictae */
3412         ret = _ri_verify_signatures(USR_APPS, pkgid, true);
3413         if (ret < 0) {
3414                 _LOGE("_ri_verify_signatures Failed : %s\n", pkgid);
3415                 ret = RPM_INSTALLER_ERR_SIG_INVALID;
3416                 goto err;
3417         }
3418
3419         /* Parse and insert manifest in DB */
3420         ret = pkgmgr_parser_parse_manifest_for_installation(pkgfilepath, NULL);
3421         if (ret < 0) {
3422                 _LOGD("Installing Manifest Failed : %s\n", pkgfilepath);
3423                 ret = RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED;
3424                 goto err;
3425         }
3426
3427         /* _ri_register_cert has __ri_free_cert_chain. */
3428         _ri_register_cert(pkgid);
3429
3430         /* search_ug_app */
3431         _coretpk_installer_search_ui_gadget(pkgid);
3432
3433         ret = RPM_INSTALLER_SUCCESS;
3434
3435 err:
3436         if (ret != 0) {
3437                 __ri_free_cert_chain();
3438         }
3439
3440         return ret;
3441 }
3442
3443 int _rpm_move_pkg(char *pkgid, int move_type)
3444 {
3445         app2ext_handle *hdl = NULL;
3446         int ret = 0;
3447         int movetype = -1;
3448         GList *dir_list = NULL;
3449         pkgmgrinfo_pkginfo_h pkghandle = NULL;
3450
3451         if (move_type == PM_MOVE_TO_INTERNAL)
3452                 movetype = APP2EXT_MOVE_TO_PHONE;
3453         else if (move_type == PM_MOVE_TO_SDCARD)
3454                 movetype = APP2EXT_MOVE_TO_EXT;
3455         else
3456                 return RPM_INSTALLER_ERR_WRONG_PARAM;
3457
3458         ret = pkgmgrinfo_pkginfo_get_pkginfo(gpkgname, &pkghandle);
3459         if (ret < 0) {
3460                 _LOGE("@failed to get the pkginfo handle!!");
3461                 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3462                 return ret;
3463         }
3464
3465         /* Terminate the running instance of app */
3466         pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, NULL);
3467         pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3468         hdl = app2ext_init(APP2EXT_SD_CARD);
3469         if ((hdl != NULL) && (hdl->interface.move != NULL)) {
3470                 dir_list = __rpm_populate_dir_list();
3471                 if (dir_list == NULL) {
3472                         _LOGE("\nError in populating the directory list\n");
3473                         return RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
3474                 }
3475                 ret = hdl->interface.move(pkgid, dir_list, movetype);
3476                 __rpm_clear_dir_list(dir_list);
3477                 if (ret != 0) {
3478                         _LOGE("Failed to move app\n");
3479                         return RPM_INSTALLER_ERR_INTERNAL;
3480                 }
3481                 app2ext_deinit(hdl);
3482                 return RPM_INSTALLER_SUCCESS;
3483         } else {
3484                 _LOGE("Failed to get app2ext handle\n");
3485                 return RPM_INSTALLER_ERR_INTERNAL;
3486         }
3487 }
3488
3489 int _rpm_process_cscxml(char *csc_script)
3490 {
3491         int ret = 0;
3492         int op_type = 0;
3493
3494         char *path_str = NULL;
3495         char *op_str = NULL;
3496         char *remove_str = NULL;
3497         char csc_str[BUF_SIZE] = { '\0' };
3498         snprintf(csc_str, BUF_SIZE - 1, "%s:", csc_script);
3499
3500         /* get params from csc script */
3501         path_str = _installer_util_get_str(csc_str, TOKEN_PATH_STR);
3502         op_str = _installer_util_get_str(csc_str, TOKEN_OPERATION_STR);
3503         remove_str = _installer_util_get_str(csc_str, TOKEN_REMOVE_STR);
3504         if ((path_str == NULL) || (op_str == NULL) || (remove_str == NULL)) {
3505                 _LOGE("csc-info : input param is null[%s, %s, %s]\n", path_str, op_str, remove_str);
3506                 goto end;
3507         }
3508         _LOGD("csc-info : path=%s, op=%s, remove=%s\n", path_str, op_str, remove_str);
3509
3510         /* get operation type */
3511         op_type = __ri_get_op_type(op_str);
3512         if (op_type < 0) {
3513                 _LOGE("csc-info : operation error[%s, %s]\n", path_str, op_str);
3514                 goto end;
3515         }
3516
3517         switch (op_type) {
3518         case INSTALL_REQ:
3519                 ret = __ri_install_csc(path_str, remove_str);
3520                 break;
3521
3522         case UPGRADE_REQ:
3523                 ret = __ri_install_csc(path_str, remove_str);
3524                 break;
3525
3526         case UNINSTALL_REQ:
3527                 ret = __ri_uninstall_csc(path_str);
3528                 break;
3529
3530         default:
3531                 break;
3532         }
3533
3534         if (ret < 0)
3535                 _LOGE("fota-info : Fota fail [pkgid=%s, operation=%d]\n", path_str, op_type);
3536
3537 end:
3538         if (path_str)
3539                 free(path_str);
3540         if (op_str)
3541                 free(op_str);
3542         if (remove_str)
3543                 free(remove_str);
3544
3545         return ret;
3546 }
3547
3548 int __ri_copy_smack_rule_file(int op, const char *pkgname, int is_system)
3549 {
3550         mode_t mode = DIR_PERMS;
3551         int ret = RPM_INSTALLER_SUCCESS;
3552         char src[BUF_SIZE] = { 0 };
3553         char dest[BUF_SIZE] = { 0 };
3554         char buf[BUF_SIZE] = { 0, };
3555
3556         switch (op) {
3557         case UNINSTALL_REQ:
3558                 /* For downloadable native app, restore the smack file.
3559                    Otherwise, remove the stored smack file. */
3560                 snprintf(dest, BUF_SIZE - 1, "%s/%s.rule", SMACK_RULES_ALT_PATH, pkgname);
3561                 snprintf(src, BUF_SIZE - 1, "%s%s.rule", DIR_RPM_WGT_SMACK_RULE_OPT, pkgname);
3562                 _LOGD("#src:[%s] dest:[%s]", src, dest);
3563
3564                 if (!is_system) {
3565                         if (!access(src, F_OK)) {
3566                                 ret = remove(src);
3567                                 if (!ret) {
3568                                         _LOGD("#File [%s] deleted.", src);
3569                                 } else {
3570                                         if( strerror_r(errno, buf, sizeof(buf)) == 0) {
3571                                                 _LOGE("@Unable to delete the file [%s], error:(%s)", src, buf);
3572                                         }
3573                                         ret = RPM_INSTALLER_ERR_INTERNAL;
3574                                         goto end;
3575                                 }
3576                         }
3577                         if (!access(dest, F_OK)) {
3578                                 ret = remove(dest);
3579                                 if (!ret) {
3580                                         _LOGD("#File [%s] deleted.", dest);
3581                                 } else {
3582                                         if( strerror_r(errno, buf, sizeof(buf)) == 0) {
3583                                                 _LOGE("@Unable to delete the file [%s], error:(%s)", dest, buf);
3584                                         }
3585                                         ret = RPM_INSTALLER_ERR_INTERNAL;
3586                                         goto end;
3587                                 }
3588                         }
3589                 } else {
3590                         _LOGD("#Restore smack files for uninstallation [%s]", pkgname);
3591                         if (!access(src, F_OK)) {
3592                                 _LOGD("#Copying [%s] to [%s]", src, dest);
3593                                 ret = __copy_file(src, dest);
3594                                 if (!ret) {
3595                                         ret = remove(src);
3596                                         if (!ret) {
3597                                                 _LOGD("#File [%s] deleted.", src);
3598                                         } else {
3599                                                 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
3600                                                         _LOGE("@Unable to delete the file [%s], error:(%s)", src, buf);
3601                                                 }
3602                                                 ret = RPM_INSTALLER_ERR_INTERNAL;
3603                                                 goto end;
3604                                         }
3605                                 } else {
3606                                         _LOGE("@Copy Failed!!");
3607                                         ret = RPM_INSTALLER_ERR_INTERNAL;
3608                                         goto end;
3609                                 }
3610                         } else {
3611                                 _LOGE("@ %s.rule file is not preserved", pkgname);
3612                         }
3613                 }
3614                 break;
3615         case UPGRADE_REQ:
3616                 _LOGD("#Preserve the smack file for upgrade [%s]", pkgname);
3617
3618                 /* Apply the new smack file and preserve the old smack rule file
3619                    if it is not preserved. */
3620                 snprintf(src, BUF_SIZE - 1, "%s/%s.rule", SMACK_RULES_ALT_PATH, pkgname);
3621                 snprintf(dest, BUF_SIZE - 1, "%s%s.rule", DIR_RPM_WGT_SMACK_RULE_OPT, pkgname);
3622
3623                 _LOGD("#src[%s] dest[%s]", src, dest);
3624
3625                 /* Create the directory if not exist to preserve the smack files */
3626                 if (mkdir(DIR_RPM_WGT_SMACK_RULE_OPT, mode) == 0 || errno == EEXIST) {
3627                         if ((access(src, F_OK) == 0) && (access(dest, F_OK) != 0)) {
3628                                 ret = __copy_file(src, dest);
3629                         } else {
3630                                 _LOGD("#Smack file is already preserved");
3631                         }
3632                 } else {
3633                         _LOGE("@Temporary folder creation failed");
3634                         ret = RPM_INSTALLER_ERR_INTERNAL;
3635                 }
3636                 break;
3637         default:
3638                 _LOGE("@Unsupported Operation\n");
3639                 ret = RPM_INSTALLER_ERR_INTERNAL;
3640         }
3641  end:
3642         return ret;
3643 }
3644
3645 int __get_smack_label_from_xml(const char *manifest, const char *pkgid, char **label)
3646 {
3647         const char *val = NULL;
3648         char pkgpath[BUF_SIZE] = { '\0' };
3649         const xmlChar *node;
3650         xmlTextReaderPtr reader;
3651         int ret = PMINFO_R_OK;
3652
3653         if (label == NULL) {
3654                 _LOGE("space for label is NULL\n");
3655                 return PMINFO_R_ERROR;
3656         }
3657
3658         *label = NULL;
3659
3660         if (pkgid == NULL) {
3661                 _LOGE("pkgid is NULL\n");
3662                 return PMINFO_R_ERROR;
3663         }
3664
3665         if (manifest == NULL) {
3666                 _LOGE("manifest is NULL\n");
3667                 *label = strdup(pkgid);
3668                 return PMINFO_R_ERROR;
3669         }
3670
3671         snprintf(pkgpath, BUF_SIZE, "%s/%s/tizen-manifest.xml", OPT_USR_APPS, pkgid);
3672         if (access(pkgpath, R_OK) == 0) {
3673                 _LOGE("This is a core tpk package");
3674                 *label = strdup(pkgid);
3675                 return 0;
3676         }
3677
3678         reader = xmlReaderForFile(manifest, NULL, 0);
3679
3680         if (reader) {
3681                 if (_child_element(reader, -1)) {
3682                         node = xmlTextReaderConstName(reader);
3683                         if (!node) {
3684                                 _LOGE("xmlTextReaderConstName value is NULL\n");
3685                                 ret = PMINFO_R_ERROR;
3686                                 goto end;
3687                         }
3688
3689                         if (!strcmp(ASCII(node), "manifest")) {
3690                                 ret = _ri_get_attribute(reader, "smack-label", &val);
3691                                 if (ret != 0) {
3692                                         _LOGE("@Error in getting the attribute value");
3693                                         ret = PMINFO_R_ERROR;
3694                                         goto end;
3695                                 }
3696                                 if (val) {
3697                                         *label = strdup(val);
3698                                         if (*label == NULL) {
3699                                                 _LOGE("Out of memeory\n");
3700                                                 ret = PMINFO_R_ERROR;
3701                                         }
3702                                         free((void *)val);
3703                                 } else {
3704                                         *label = NULL;
3705                                         _LOGE("package smack-label is not specified\n");
3706                                         goto end;
3707                                 }
3708                         } else {
3709                                 _LOGE("Unable to create xml reader\n");
3710                                 ret = PMINFO_R_ERROR;
3711                                 goto end;
3712                         }
3713                 }
3714         } else {
3715                 _LOGE("xmlReaderForFile value is NULL\n");
3716                 ret = PMINFO_R_ERROR;
3717         }
3718
3719  end:
3720
3721         xmlFreeTextReader(reader);
3722
3723         if (*label == NULL) {
3724                 *label = strdup(pkgid);
3725         }
3726
3727         return ret;
3728 }
3729
3730 int __get_smack_label_from_db(const char *pkgid, char **label)
3731 {
3732         char *smack_label = NULL;
3733         pkgmgrinfo_pkginfo_h handle = NULL;
3734         int ret = PMINFO_R_OK;
3735
3736         if (label == NULL) {
3737                 _LOGE("space for label is NULL\n");
3738                 return PMINFO_R_ERROR;
3739         }
3740
3741         *label = NULL;
3742
3743         if (pkgid == NULL) {
3744                 _LOGE("pkgid is NULL\n");
3745                 return PMINFO_R_ERROR;
3746         }
3747
3748         ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
3749         if (ret != PMINFO_R_OK) {
3750                 _LOGE("failed to get pkginfo\n");
3751                 ret = PMINFO_R_ERROR;
3752                 goto end;
3753         }
3754         ret = pkgmgrinfo_pkginfo_get_custom_smack_label(handle, &smack_label);
3755         if (ret != PMINFO_R_OK) {
3756                 _LOGE("failed to get custom smack_label\n");
3757                 ret = PMINFO_R_ERROR;
3758                 goto end;
3759         }
3760
3761         _LOGD("smack_label(%s)\n", smack_label);
3762         if (smack_label) {
3763                 *label = strdup(smack_label);
3764         }
3765
3766  end:
3767         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
3768
3769         if (*label == NULL) {
3770                 *label = strdup(pkgid);
3771         }
3772
3773         return ret;
3774 }