Update source from tizen 2.3
[platform/core/base/rpm-installer.git] / backend / src / coretpk / xml-parser / coretpk-parser-hybrid.c
1 /*
2  * coretpk-installer
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, junsuk.oh <junsuk77.oh@samsung.com>,
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #define _GNU_SOURCE
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <sys/stat.h>
27 #include <pkgmgr-info.h>
28 #include <pkgmgr_parser.h>
29 #include <privilege-control.h>
30
31 #include "coretpk-installer-internal.h"
32 #include "rpm-installer-util.h"
33 #include "rpm-installer.h"
34
35 #define LOG_PRINT_LINE_MAX 20
36 #define LOG_BUFFER_COUNT_MAX 4096
37
38 static int __coretpk_parser_hybrid_to_file(const char *web_xml, const char *core_xml);
39 static int __coretpk_parser_hybrid_merge_privilege(char* merged_buf, char* core_buf, int* filesize);
40 static int __coretpk_parser_hybrid_merge_ui_application(char* merged_buf, char* core_buf, int* filesize);
41 static int __coretpk_parser_hybrid_merge_service_application(char* merged_buf, char* core_buf, int* filesize);
42 static int __coretpk_parser_hybrid_merge_tag(char* merged_buf, char* core_buf, int* filesize, const char* start_tag, const char* end_tag);
43
44 static int __coretpk_parser_hybrid_get_part(const char* start_point, const char* start_tag, const char* end_tag, char** buf, int* length, char** next);
45 static int __coretpk_parser_hybrid_merge_to(const char* merged_buf, int* filesize, const char* tag, const char* buf, int length);
46 static int __coretpk_parser_hybrid_dump_log_data(char *data, int length);
47
48 static int _coretpk_installer_hybrid_convert_manifest(char *manifest, const char* pkgid);
49
50 int __coretpk_parser_hybrid_to_file(const char *web_xml, const char *core_xml)
51 {
52         int ret = RPM_INSTALLER_ERR_WRONG_PARAM;
53         int res = 0;
54         FILE* web_xml_file = NULL;
55         FILE* core_xml_file = NULL;
56         struct stat web_fileinfo;
57         struct stat core_fileinfo;
58         int web_xml_filesize = 0;
59         int core_xml_filesize = 0;
60         int merged_size = 0;
61         char* merged_buf = NULL;
62         char* core_buf = NULL;
63         int read_bytes = 0;
64         char* manifest_tag = NULL;
65         int filesize = 0;
66         FILE* result_xml_file = NULL;
67         int result_write_bytes = 0;
68
69         res = stat(web_xml, &web_fileinfo);
70         tryvm_if(res < 0, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "fstat() failed, web_xml=[%s]\n", web_xml);
71
72         res = stat(core_xml, &core_fileinfo);
73         tryvm_if(res < 0, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "fstat() failed, core_xml=[%s]\n", core_xml);
74
75         web_xml_filesize = web_fileinfo.st_size;
76         core_xml_filesize = core_fileinfo.st_size;
77         merged_size = web_xml_filesize + core_xml_filesize;
78
79         web_xml_file = fopen(web_xml, "r");
80         tryvm_if(web_xml_file == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "fopen() failed, web_xml=[%s]\n", web_xml);
81
82         merged_buf = (char*)calloc(1, merged_size + 1);
83         tryvm_if(merged_buf == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "merged_buf is NULL");
84
85         read_bytes = fread(merged_buf, 1, web_xml_filesize, web_xml_file);
86         tryvm_if(read_bytes <= 0, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "fread() failed, web_xml=[%s]", web_xml);
87
88         core_xml_file = fopen(core_xml, "r");
89         tryvm_if(core_xml_file == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "fopen() failed, core_xml=[%s]\n", core_xml);
90
91         core_buf = (char*)calloc(1, core_xml_filesize + 1);
92         tryvm_if(core_buf == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "core_buf is NULL");
93
94         read_bytes = fread(core_buf, 1, core_xml_filesize, core_xml_file);
95         tryvm_if(read_bytes <= 0, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "fread() failed, core_xml=[%s]", core_xml);
96         core_buf[read_bytes] = '\0';
97
98         manifest_tag = strcasestr(merged_buf, "</manifest>");
99         tryvm_if(manifest_tag == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "manifest_tag is NULL");
100
101         filesize = web_xml_filesize;
102
103         __coretpk_parser_hybrid_merge_privilege(merged_buf, core_buf, &filesize);
104         __coretpk_parser_hybrid_merge_ui_application(merged_buf, core_buf, &filesize);
105         __coretpk_parser_hybrid_merge_service_application(merged_buf, core_buf, &filesize);
106
107         result_xml_file = fopen(web_xml, "w");
108         tryvm_if(result_xml_file == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "fopen() failed, result_xml=[%s]", web_xml);
109
110         result_write_bytes = fwrite(merged_buf, 1, filesize, result_xml_file);
111         tryvm_if(result_write_bytes != filesize, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "fwrite() failed, result_write_bytes=[%d]", result_write_bytes);
112
113
114     ret = RPM_INSTALLER_SUCCESS;
115
116 catch:
117
118         if(result_xml_file != NULL){
119                 fclose(result_xml_file);
120                 result_xml_file = NULL;
121         }
122         if(core_xml_file != NULL){
123                 fclose(core_xml_file);
124                 core_xml_file = NULL;
125         }
126         if(web_xml_file != NULL){
127                 fclose(web_xml_file);
128                 web_xml_file = NULL;
129         }
130         FREE_AND_NULL(merged_buf);
131         FREE_AND_NULL(core_buf);
132         return ret;
133 }
134
135 int __coretpk_parser_hybrid_merge_privilege(char* merged_buf, char* core_buf, int* filesize)
136 {
137         int ret = RPM_INSTALLER_ERR_WRONG_PARAM;
138         char* merged_privilege_detected = NULL;
139         char* merged_point = NULL;
140         char* core_privilege_start = NULL;
141         char* core_privilege_end = NULL;
142         int privilege_len = 0;
143         int core_buf_len = 0;
144         char* selected_privilege_buf = NULL;
145
146         retvm_if(merged_buf == NULL, RPM_INSTALLER_ERR_WRONG_PARAM, "merged_buf is NULL");
147         retvm_if(core_buf == NULL, RPM_INSTALLER_ERR_WRONG_PARAM, "core_buf is NULL");
148         retvm_if(filesize <= 0, RPM_INSTALLER_ERR_WRONG_PARAM, "filesize is NULL");
149
150         if (strcasestr(core_buf, "</privileges>") == NULL) {
151                 return RPM_INSTALLER_SUCCESS;
152     }
153
154         merged_privilege_detected = strcasestr(merged_buf, "</privileges>");
155         core_buf_len = strlen(core_buf);
156
157         selected_privilege_buf = (char*)calloc(1, core_buf_len + 1);
158         tryvm_if(selected_privilege_buf == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "selected_privilege_buf is NULL");
159
160         if (merged_privilege_detected == NULL) {
161                 _LOGD("no privileges are detected in web xml");
162
163                 core_privilege_start = strcasestr(core_buf, "<privileges>");
164                 core_privilege_end = strcasestr(core_buf, "</privileges>");
165
166                 privilege_len = core_privilege_end - core_privilege_start + strlen("</privileges>");
167                 merged_point = strcasestr(merged_buf, "<ui-application");
168
169                 _LOGD("inserted privileges of core xml");
170                 __coretpk_parser_hybrid_dump_log_data(core_privilege_start, privilege_len);
171         } else {
172                 char* privilege_buf = NULL;
173                 char* each_privilege_start = NULL;
174                 char* each_privilege_end = NULL;
175                 int each_privilege_len = 0;
176                 char each_privilege_buf[512] = {0};
177
178                 _LOGD("privileges are detected in web xml");
179
180                 core_privilege_start = strcasestr(core_buf, "<privilege>");
181                 core_privilege_end = strcasestr(core_buf, "</privileges>");
182
183                 privilege_len = core_privilege_end - core_privilege_start;
184                 merged_point = strcasestr(merged_buf, "</privileges>");
185
186                 _LOGD("original privilege of core xml");
187                 __coretpk_parser_hybrid_dump_log_data(core_privilege_start, privilege_len);
188
189                 privilege_buf = (char*)calloc(1, privilege_len + 1);
190                 tryvm_if(privilege_buf == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "privilege_buf is NULL");
191                 strncpy(privilege_buf, core_privilege_start, privilege_len);
192
193                 each_privilege_start = privilege_buf;
194
195                 while (each_privilege_start && (each_privilege_start < privilege_buf + privilege_len))
196                 {
197                         each_privilege_end = strcasestr(each_privilege_start, "</privilege>");
198                         each_privilege_len = each_privilege_end - each_privilege_start + strlen("</privilege>");
199                         if ((each_privilege_end > 0) && each_privilege_len > 0)
200                         {
201                                 memset(each_privilege_buf, 0, sizeof(each_privilege_buf));
202                                 memcpy(each_privilege_buf, each_privilege_start, each_privilege_len);
203                                 _LOGD("[%s]", each_privilege_buf);
204
205                         if (strcasestr(merged_buf, each_privilege_buf) == 0)
206                         {
207                                 strncat(selected_privilege_buf, each_privilege_buf, core_buf_len);
208                         }
209                         else
210                         {
211                                 _LOGD("this privilege is discarded, [%s]", each_privilege_buf);
212                         }
213                         }
214                         else
215                         {
216                                 _LOGD("end of privileges merging");
217                                 break;
218                         }
219
220                                 each_privilege_start = strcasestr(each_privilege_end, "<privilege>");
221                 }
222
223                 core_privilege_start = selected_privilege_buf;
224                 privilege_len = strlen(core_privilege_start);
225
226                 _LOGD("filtered privileges of core xml");
227                 __coretpk_parser_hybrid_dump_log_data(core_privilege_start, privilege_len);
228                 FREE_AND_NULL(privilege_buf);
229         }
230
231         if ((merged_point > 0) && (core_privilege_start > 0) && (privilege_len > 0))
232         {
233                 int last_part_len = 0;
234                 char* last_part_buf = NULL;
235
236                 last_part_len = *filesize - (merged_point - merged_buf);
237                 last_part_buf = (char*)calloc(1, *filesize + 1);
238                 tryvm_if(last_part_buf == NULL, ret = RPM_INSTALLER_ERR_INTERNAL,"@calloc failed!!");
239
240                 if (last_part_len > 0)
241                 {
242                         memcpy(last_part_buf, merged_point, last_part_len);
243
244                         _LOGD("last part of merged xml for backup");
245                         __coretpk_parser_hybrid_dump_log_data(last_part_buf, last_part_len);
246
247                         memcpy(merged_point, core_privilege_start, privilege_len);
248
249                         memcpy(merged_point + privilege_len, last_part_buf, last_part_len);
250                         *filesize += privilege_len;
251                 }
252                 FREE_AND_NULL(last_part_buf);
253
254         }
255         ret = RPM_INSTALLER_SUCCESS;
256
257 catch:
258         FREE_AND_NULL(selected_privilege_buf);
259         return ret;
260 }
261
262 int __coretpk_parser_hybrid_merge_ui_application(char* merged_buf, char* core_buf, int* filesize)
263 {
264     retvm_if(merged_buf == NULL, RPM_INSTALLER_ERR_WRONG_PARAM, "merged_buf is NULL");
265     retvm_if(core_buf == NULL, RPM_INSTALLER_ERR_WRONG_PARAM, "core_buf is NULL");
266     retvm_if(filesize <= 0, RPM_INSTALLER_ERR_WRONG_PARAM, "filesize is NULL");
267
268     if (strcasestr(core_buf, "</ui-application>") == NULL)
269     {
270         _LOGD("<ui-application> is NOT detected in core xml");
271         return RPM_INSTALLER_SUCCESS;
272     }
273
274     _LOGD("<ui-application> is detected in core xml");
275     __coretpk_parser_hybrid_merge_tag(merged_buf, core_buf, filesize, "<ui-application", "</ui-application>");
276
277     return RPM_INSTALLER_SUCCESS;
278 }
279
280 int __coretpk_parser_hybrid_merge_service_application(char* merged_buf, char* core_buf, int* filesize)
281 {
282     retvm_if(merged_buf == NULL, RPM_INSTALLER_ERR_WRONG_PARAM, "merged_buf is NULL");
283     retvm_if(core_buf == NULL, RPM_INSTALLER_ERR_WRONG_PARAM, "core_buf is NULL");
284     retvm_if(filesize <= 0, RPM_INSTALLER_ERR_WRONG_PARAM, "filesize is NULL");
285
286     if (strcasestr(core_buf, "</service-application>") == NULL)
287     {
288         _LOGD("<service-application> is NOT detected in core xml");
289         return RPM_INSTALLER_SUCCESS;
290     }
291
292     _LOGD("<service-application> is detected in core xml");
293     __coretpk_parser_hybrid_merge_tag(merged_buf, core_buf, filesize, "<service-application", "</service-application>");
294
295     return RPM_INSTALLER_SUCCESS;
296 }
297
298 int __coretpk_parser_hybrid_merge_tag(char* merged_buf, char* core_buf, int* filesize, const char* start_tag, const char* end_tag)
299 {
300     do
301     {
302         char* buf = NULL;
303         int length = 0;
304         char* next = NULL;
305
306         __coretpk_parser_hybrid_get_part(core_buf, start_tag, end_tag, &buf, &length, &next);
307         if (length > 0)
308         {
309                 __coretpk_parser_hybrid_merge_to(merged_buf, filesize, "</manifest>", buf, length);
310         }
311
312         if (buf)
313                         free(buf);
314
315         core_buf = next;
316     }
317     while (core_buf > 0);
318
319     return RPM_INSTALLER_SUCCESS;
320 }
321
322 int __coretpk_parser_hybrid_get_part(const char* start_point, const char* start_tag, const char* end_tag, char** buf, int* length, char** next)
323 {
324         int ret = RPM_INSTALLER_ERR_WRONG_PARAM;
325         const char* start_buf_point = NULL;
326         const char* end_buf_point = NULL;
327         int len = 0;
328
329         tryvm_if(start_point == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "start_point is NULL");
330         tryvm_if(start_tag == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "start_tag is NULL");
331         tryvm_if(end_tag == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "end_tag is NULL");
332         tryvm_if(buf == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "buf is NULL");
333         tryvm_if(length == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "length is NULL");
334         tryvm_if(next == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "next is NULL");
335
336         start_buf_point = strcasestr(start_point, start_tag);
337         tryvm_if(start_buf_point == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "start_buf_point is NULL");
338
339         end_buf_point = strcasestr(start_buf_point, end_tag);
340         tryvm_if(end_buf_point == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "end_buf_point is NULL");
341
342         len = end_buf_point - start_buf_point + strlen(end_tag);
343         tryvm_if(len <= 0, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "len is invalid");
344
345         *buf = (char*)calloc(1, len + 1);
346         tryvm_if(*buf == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "*buf is NULL");
347         memcpy(*buf, start_buf_point, len);
348
349         _LOGD("extracted part, len=[%d]", len);
350         __coretpk_parser_hybrid_dump_log_data(*buf, len);
351
352         *length = len;
353         next = (char**)end_buf_point;
354
355         ret = RPM_INSTALLER_SUCCESS;
356
357 catch:
358     return ret;
359 }
360
361 int __coretpk_parser_hybrid_merge_to(const char* merged_buf, int* filesize, const char* tag, const char* buf, int length)
362 {
363         int ret = RPM_INSTALLER_ERR_WRONG_PARAM;
364         char* merged_point = NULL;
365         char* last_part_buf = NULL;
366         int last_part_length = 0;
367
368     tryvm_if(merged_buf == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "merged_buf is NULL");
369     tryvm_if(*filesize <= 0, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "filesize is invalid");
370     tryvm_if(tag == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "tag is NULL");
371     tryvm_if(buf == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "buf is NULL");
372     tryvm_if(length <= 0, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "length is invalid");
373
374     merged_point = (char*)strcasestr(merged_buf, tag);
375     tryvm_if(merged_point == NULL, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "tag is not found, tag=[%s]", tag);
376
377     last_part_length = *filesize - (merged_point - merged_buf);
378     last_part_buf = (char*)calloc(1, *filesize + 1);
379         tryvm_if(last_part_buf == NULL, ret = RPM_INSTALLER_ERR_INTERNAL, "@calloc failed!!");
380
381         if (last_part_length > 0)
382         {
383                 memcpy(last_part_buf, merged_point, last_part_length);
384
385                 _LOGD("last part of merged xml for backup");
386                 __coretpk_parser_hybrid_dump_log_data(last_part_buf, last_part_length);
387
388                 memcpy(merged_point, buf, length);
389                 memcpy(merged_point + length, last_part_buf, last_part_length);
390                 *filesize += length;
391         }
392
393     ret = RPM_INSTALLER_SUCCESS;
394
395 catch:
396         FREE_AND_NULL(last_part_buf);
397         return ret;
398 }
399
400 char __coretpk_parser_hybrid_log_change_hex_to_str(int hex)
401 {
402         char ch = '0';
403
404         const static char       hexValues[]     = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 0};
405
406
407         if (hex >= 0 && hex <= 0x0F)
408         {
409                 ch      = hexValues[hex];
410         }
411         else
412         {
413                 _LOGD("LogChangeHexToStr: Error! [Hex Val: %d]\n", hex);
414         }
415
416         return ch;
417 }
418
419 int __coretpk_parser_hybrid_dump_log_data(char *pData, int dataLen)
420 {
421         if(pData == NULL){
422                 _LOGE("@No data to dump");
423                 return 0;
424         }
425         const char      *szData = (const char*)pData;
426         char            ch = 0;
427         int                     i = 0, j = 0, idx = 0, idx2 = 0, high = 0, low = 0, temp = 0;
428
429         char            buf[LOG_PRINT_LINE_MAX + 2]                     = {0};
430         char            buf2[(LOG_PRINT_LINE_MAX + 2) * 3]      = {0};
431         char            buf_out[sizeof(buf) + sizeof(buf2) + 1] = {0};
432
433
434         if (dataLen > LOG_BUFFER_COUNT_MAX)
435         {
436                 dataLen = LOG_BUFFER_COUNT_MAX;
437         }
438
439         _LOGD("------------------------------------------");
440
441         while (i < (int)dataLen)
442         {
443                 ch      = szData[i];
444
445                 /* make ascii table */
446                 if (ch >= 32 && ch <= 128)
447                 {
448                         buf[idx++]      = ch;
449                 }
450                 else
451                         buf[idx++]      = '.';
452
453                 // make binary table
454                 high = (ch & 0xf0)>>4;
455                 low = ch & 0x0f;
456
457                 buf2[idx2++]    = __coretpk_parser_hybrid_log_change_hex_to_str(high);
458                 buf2[idx2++]    = __coretpk_parser_hybrid_log_change_hex_to_str(low);
459                 buf2[idx2++]    = ' ';
460
461                 if (idx >= LOG_PRINT_LINE_MAX)
462                 {
463                         memcpy(buf_out, buf2, idx2);
464
465                         buf_out[idx2++] = ' ';
466                         buf_out[idx2++] = ' ';
467
468                         memcpy(buf_out + idx2, buf, idx);
469                         buf_out[idx2+idx]       = '\0';
470
471                         idx             = 0;
472                         idx2    = 0;
473
474                         _LOGD("%s\n", buf_out);
475                 }
476
477                 i++;
478         }
479
480         // last line
481         if (idx > 0)
482         {
483                 memcpy(buf_out, buf2, idx2);
484                 temp    = idx2;
485
486                 for (j = 0; j < (LOG_PRINT_LINE_MAX * 3) - temp; j++)
487                 {
488                         buf_out[idx2++] = ' ';
489                 }
490
491                 buf_out[idx2++] = ' ';
492                 buf_out[idx2++] = ' ';
493
494                 memcpy(buf_out+idx2, buf, idx);
495                 buf_out[idx2+idx]       = '\0';
496
497                 _LOGD("%s\n", buf_out);
498         }
499
500         _LOGD("------------------------------------------");
501
502         return 0;
503 }
504
505 #if 0
506 static void __coretpk_parser_hybrid_clean_db(const char *pkgid)
507 {
508     retm_if(pkgid == NULL, "pkgid is NULL");
509
510         int ret = 0;
511         pkgmgrinfo_pkginfo_h handle = NULL;
512
513         ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
514         if ((ret < 0) || (handle == NULL)) {
515                 _LOGD("pkgid[%s] dont have package info", pkgid);
516         } else {
517                 _LOGD("pkgid[%s] have package info, need clean db for hybrid", pkgid);
518                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
519
520                 //request pkginfo unregister
521                 ret = pkgmgr_parser_parse_manifest_for_uninstallation(pkgid, NULL);
522                 if (ret < 0)
523                         _LOGE("[%s]fail delete pkg info", pkgid);
524         }
525 }
526 #endif
527
528 int _coretpk_installer_hybrid_convert_manifest(char *manifest, const char* pkgid)
529 {
530         int ret = 0;
531         char outputxml[BUF_SIZE] = {'\0'};
532
533         ret = mkdir(TEMP_XML_DIR, DIRECTORY_PERMISSION_755);
534         if (ret != 0) {
535                 _LOGL("mkdir()", errno);
536                 return RPM_INSTALLER_ERR_INTERNAL;
537         }
538
539         // run script
540         snprintf(outputxml, BUF_SIZE, "%s/%s", TEMP_XML_DIR, CORETPK_XML);
541         _LOGD("input xml = [%s], out xml = [%s]", manifest, outputxml);
542
543         const char *unzip_argv_rw[] = { CORETPK_RW_XML_CONVERTER, manifest, outputxml, pkgid, NULL, NULL };
544         const char *unzip_argv_ro[] = { CORETPK_RO_XML_CONVERTER, manifest, outputxml, pkgid, NULL, NULL };
545
546         if (strstr(manifest, OPT_USR_APPS)) {
547                 ret = _ri_xsystem(unzip_argv_rw);
548         } else {
549                 ret = _ri_xsystem(unzip_argv_ro);
550         }
551
552         if (ret != 0) {
553                 _LOGL("converting the manifest file", errno);
554                 return RPM_INSTALLER_ERR_INTERNAL;
555         }
556
557         return ret;
558 }
559
560 int _coretpk_installer_request_hybrid(int hybridOperation, char *pPkgPath, int apiVisibility)
561 {
562         retvm_if(pPkgPath == NULL, RPM_INSTALLER_ERR_WRONG_PARAM, "pPkgPath is NULL.");
563
564         int ret = 0;
565         char wgt_xml[BUF_SIZE] = {'\0'};
566         char core_xml[BUF_SIZE] = {'\0'};
567         char converted_core_xml[BUF_SIZE] = {'\0'};
568         char native_id[BUF_SIZE] = {0,};
569         manifest_x *mfx = NULL;
570
571         _LOGD("request_hybrid(%s) start.", pPkgPath);
572
573         snprintf(core_xml, BUF_SIZE, "%s/%s", pPkgPath, CORETPK_XML);
574         retvm_if(access(core_xml, F_OK) != 0, RPM_INSTALLER_ERR_WRONG_PARAM, "cannot access core xml. [%s]", core_xml);
575
576         _LOGD("core xml = [%s]", core_xml);
577
578         // get pkgid and version from xml file
579         mfx = pkgmgr_parser_process_manifest_xml(core_xml);
580         retvm_if(mfx == NULL, RPM_INSTALLER_ERR_WRONG_PARAM, "pkgmgr_parser_process_manifest_xml(%s) failed.", core_xml);
581
582         _LOGD("pkgid = [%s], version = [%s]", mfx->package, mfx->version);
583
584 #if 0
585         // clean pkgmgr db
586         __coretpk_parser_hybrid_clean_db(mfx->package);
587         _LOGD("hybrid_clean_db(%s) called.", mfx->package);
588 #endif
589
590         if (strstr(pPkgPath, OPT_USR_APPS)) {
591                 snprintf(wgt_xml, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, mfx->package);
592         } else {
593                 snprintf(wgt_xml, BUF_SIZE, "%s/%s.xml", USR_SHARE_PACKAGES, mfx->package);
594         }
595
596         _LOGD("wgt xml = [%s]", wgt_xml);
597
598         // convert core xml
599         ret = _coretpk_installer_hybrid_convert_manifest(core_xml, mfx->package);
600         if (ret != 0) {
601                 _LOGD("_coretpk_installer_hybrid_convert_manifest(%s, %s) failed.", core_xml, mfx->package);
602                 pkgmgr_parser_free_manifest_xml(mfx);
603                 return -1;
604         }
605
606         snprintf(converted_core_xml, BUF_SIZE, "%s/%s", TEMP_XML_DIR, CORETPK_XML);
607         _LOGD("hybrid_convert_manifest(%s) is done.", converted_core_xml);
608
609         // merge xml start
610         ret = __coretpk_parser_hybrid_to_file(wgt_xml, converted_core_xml);
611         //tryvm_if(ret != 0, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "__coretpk_parser_hybrid_to_file(%s, %s) failed.", wgt_xml, converted_core_xml);
612         _LOGD("hybrid_to_file(%s, %s) success", wgt_xml, converted_core_xml);
613
614         // make directory
615         ret = _coretpk_installer_make_directory((char*)mfx->package);
616         //tryvm_if(ret != 0, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "_coretpk_installer_make_directory(%s) failed.", mfx->package);
617         _LOGD("make_directory(%s) success", mfx->package);
618
619         // apply smack to app dir
620         ret = _coretpk_installer_apply_smack((char*)mfx->package, 1);
621         //tryvm_if(ret != 0, ret = RPM_INSTALLER_ERR_WRONG_PARAM, "@Failed to apply_smack");
622         _LOGD("apply_smack(%s, %d) success", mfx->package, ret);
623
624         // apply smack by privilege
625         strcat(native_id, (char*)mfx->package);
626         strcat(native_id, ".native");
627
628         ret = _ri_privilege_register_package(native_id);
629         if (ret != 0) {
630                 _LOGE("_ri_privilege_register_package(%s) failed. ret = [%d].", native_id, ret);
631         } else {
632                 _LOGD("_ri_privilege_register_package(%s) success.", native_id);
633         }
634
635         ret = _coretpk_installer_apply_privilege(native_id, pPkgPath, apiVisibility);
636         if (ret != 0) {
637                 _LOGE("_coretpk_installer_apply_privilege(%s) failed. ret = [%d].", native_id, ret);
638         } else {
639                 _LOGD("_coretpk_installer_apply_privilege(%s) success.", native_id);
640         }
641
642         ret = perm_app_add_friend((char*)mfx->package, native_id);
643         if (ret != 0) {
644                 _LOGE("perm_app_add_friend(%s, %s, %d) failed", mfx->package, native_id, ret);
645         } else {
646                 _LOGD("perm_app_add_friend(%s) success.", native_id);
647         }
648
649         pkgmgr_parser_free_manifest_xml(mfx);
650
651         const char *delete_argv[] = {"/bin/rm", "-rf", TEMP_XML_DIR, NULL};
652         ret = _ri_xsystem(delete_argv);
653         if(ret != 0){
654                 _LOGE("delete the directory failed. [%s]",TEMP_XML_DIR);
655                 //return RPM_INSTALLER_ERR_INTERNAL;
656         }
657
658         _LOGD("request_hybrid(%s) end.", pPkgPath);
659         return 0;
660 }