Modify symbolic of rpm-backend in post script for TC-321
[platform/core/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 <glib.h>
38 #include <ctype.h>              /* for isspace () */
39 #include <pkgmgr-info.h>
40 #include <pkgmgr_parser.h>
41 #include <package-manager.h>
42
43 #include "rpm-installer-util.h"
44 #include "rpm-installer.h"
45 #include "rpm-frontend.h"
46
47 #define PRE_CHECK_FOR_MANIFEST
48 #define INSTALL_SCRIPT          "/usr/bin/install_rpm_package.sh"
49 #define UNINSTALL_SCRIPT        "/usr/bin/uninstall_rpm_package.sh"
50 #define UPGRADE_SCRIPT  "/usr/bin/upgrade_rpm_package.sh"
51 #define RPM2CPIO        "/usr/bin/rpm2cpio"
52
53 enum rpm_request_type {
54         INSTALL_REQ,
55         UNINSTALL_REQ,
56         UPGRADE_REQ,
57 };
58
59 #define APP2EXT_ENABLE
60 #ifdef APP2EXT_ENABLE
61 #include <app2ext_interface.h>
62 #endif
63
64 typedef enum rpm_request_type rpm_request_type;
65 extern char *gpkgname;
66
67 static int __rpm_xsystem(const char *argv[]);
68 static void __rpm_process_line(char *line);
69 static void __rpm_perform_read(int fd);
70 static void __rpm_clear_dir_list(GList* dir_list);
71 static GList * __rpm_populate_dir_list();
72
73 static void __rpm_process_line(char *line)
74 {
75         char *tok = NULL;
76         tok = strtok(line, " ");
77         if (tok) {
78                 if (!strncmp(tok, "%%", 2)) {
79                         tok = strtok(NULL, " ");
80                         if (tok) {
81                                 _d_msg(DEBUG_INFO, "Install percentage is %s\n",
82                                        tok);
83                                 _ri_broadcast_status_notification(gpkgname,
84                                                                   "install_percent",
85                                                                   tok);
86                                 _ri_stat_cb(gpkgname, "install_percent", tok);
87                         }
88                         return;
89                 }
90         }
91         return;
92 }
93
94 static void __rpm_perform_read(int fd)
95 {
96         char *buf_ptr = NULL;
97         char *tmp_ptr = NULL;
98         int size = 0;
99         static char buffer[1024] = { 0, };
100         static int buffer_position;
101
102         size = read(fd, &buffer[buffer_position],
103                     sizeof(buffer) - buffer_position);
104         buffer_position += size;
105         if (size <= 0)
106                 return;
107
108         /* Process each line of the recieved buffer */
109         buf_ptr = tmp_ptr = buffer;
110         while ((tmp_ptr = (char *)memchr(buf_ptr, '\n',
111                                          buffer + buffer_position - buf_ptr)) !=
112                NULL) {
113                 *tmp_ptr = 0;
114                 __rpm_process_line(buf_ptr);
115                 /* move to next line and continue */
116                 buf_ptr = tmp_ptr + 1;
117         }
118
119         /*move the remaining bits at the start of the buffer
120            and update the buffer position */
121         buf_ptr = (char *)memrchr(buffer, 0, buffer_position);
122         if (buf_ptr == NULL)
123                 return;
124
125         /* we have processed till the last \n which has now become
126            0x0. So we increase the pointer to next position */
127         buf_ptr++;
128
129         memmove(buffer, buf_ptr, buf_ptr - buffer);
130         buffer_position = buffer + buffer_position - buf_ptr;
131 }
132
133 static int __rpm_xsystem(const char *argv[])
134 {
135         int err = 0;
136         int status = 0;
137         pid_t pid;
138         int pipefd[2];
139
140         if (pipe(pipefd) == -1) {
141                 _d_msg(DEBUG_ERR, "pipe creation failed\n");
142                 return -1;
143         }
144         /*Read progress info via pipe */
145         pid = fork();
146
147         switch (pid) {
148         case -1:
149                 _d_msg(DEBUG_ERR, "fork failed\n");
150                 return -1;
151         case 0:
152                 /* child */
153                 {
154                         close(pipefd[0]);
155                         close(1);
156                         close(2);
157                         dup(pipefd[1]);
158                         dup(pipefd[1]);
159                         if (execvp(argv[0], (char *const *)argv) == -1) {
160                                 _d_msg(DEBUG_ERR, "execvp failed\n");
161                         }
162                         _exit(100);
163                 }
164         default:
165                 /* parent */
166                 break;
167         }
168
169         close(pipefd[1]);
170
171         while ((err = waitpid(pid, &status, WNOHANG)) != pid) {
172                 if (err < 0) {
173                         if (errno == EINTR)
174                                 continue;
175                         _d_msg(DEBUG_ERR, "waitpid failed\n");
176                         close(pipefd[0]);
177                         return -1;
178                 }
179
180                 int select_ret;
181                 fd_set rfds;
182                 struct timespec tv;
183                 FD_ZERO(&rfds);
184                 FD_SET(pipefd[0], &rfds);
185                 tv.tv_sec = 1;
186                 tv.tv_nsec = 0;
187                 select_ret =
188                     pselect(pipefd[0] + 1, &rfds, NULL, NULL, &tv, NULL);
189                 if (select_ret == 0)
190                         continue;
191
192                 else if (select_ret < 0 && errno == EINTR)
193                         continue;
194                 else if (select_ret < 0) {
195                         _d_msg(DEBUG_ERR, "select() returned error\n");
196                         continue;
197                 }
198                 if (FD_ISSET(pipefd[0], &rfds))
199                         __rpm_perform_read(pipefd[0]);
200         }
201
202         close(pipefd[0]);
203         /* Check for an error code. */
204         if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0) {
205
206                 if (WIFSIGNALED(status) != 0 && WTERMSIG(status) == SIGSEGV) {
207                         printf
208                             ("Sub-process %s received a segmentation fault. \n",
209                              argv[0]);
210                 } else if (WIFEXITED(status) != 0) {
211                         printf("Sub-process %s returned an error code (%u)\n",
212                                argv[0], WEXITSTATUS(status));
213                 } else {
214                         printf("Sub-process %s exited unexpectedly\n", argv[0]);
215                 }
216         }
217         return WEXITSTATUS(status);
218 }
219
220 static void __rpm_clear_dir_list(GList* dir_list)
221 {
222         GList *list = NULL;
223         app2ext_dir_details* dir_detail = NULL;
224         if (dir_list) {
225                 list = g_list_first(dir_list);
226                 while (list) {
227                         dir_detail = (app2ext_dir_details *)list->data;
228                         if (dir_detail && dir_detail->name) {
229                                 free(dir_detail->name);
230                         }
231                         list = g_list_next(list);
232                 }
233                 g_list_free(dir_list);
234         }
235 }
236
237 static GList * __rpm_populate_dir_list()
238 {
239         GList *dir_list = NULL;
240         GList *list = NULL;
241         app2ext_dir_details* dir_detail = NULL;
242         int i;
243         char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
244
245
246         for (i=0; i<3; i++) {
247                 dir_detail = (app2ext_dir_details*) calloc(1, sizeof(app2ext_dir_details));
248                 if (dir_detail == NULL) {
249                         printf("\nMemory allocation failed\n");
250                         goto FINISH_OFF;
251                 }
252                 dir_detail->name = (char*) calloc(1, sizeof(char)*(strlen(pkg_ro_content_rpm[i])+2));
253                 if (dir_detail->name == NULL) {
254                         printf("\nMemory allocation failed\n");
255                         free(dir_detail);
256                         goto FINISH_OFF;
257                 }
258                 snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i])+1), "%s", pkg_ro_content_rpm[i]);
259                 dir_detail->type = APP2EXT_DIR_RO;
260                 dir_list = g_list_append(dir_list, dir_detail);
261         }
262         if (dir_list) {
263                 list = g_list_first(dir_list);
264                 while (list) {
265                         dir_detail = (app2ext_dir_details *)list->data;
266                         list = g_list_next(list);
267                 }
268         }
269         return dir_list;
270 FINISH_OFF:
271         if (dir_list) {
272                 list = g_list_first(dir_list);
273                 while (list) {
274                         dir_detail = (app2ext_dir_details *)list->data;
275                         if (dir_detail && dir_detail->name) {
276                                 free(dir_detail->name);
277                         }
278                         list = g_list_next(list);
279                 }
280                 g_list_free(dir_list);
281         }
282         return NULL;
283 }
284
285 static GList * __rpm_move_dir_list()
286 {
287         GList *dir_list = NULL;
288         GList *list = NULL;
289         app2ext_dir_details* dir_detail = NULL;
290         int i;
291         char pkg_ro_content_rpm[3][5] = { "bin", "res", };
292
293
294         for (i=0; i<3; i++) {
295                 dir_detail = (app2ext_dir_details*) calloc(1, sizeof(app2ext_dir_details));
296                 if (dir_detail == NULL) {
297                         printf("\nMemory allocation failed\n");
298                         goto FINISH_OFF;
299                 }
300                 dir_detail->name = (char*) calloc(1, sizeof(char)*(strlen(pkg_ro_content_rpm[i])+2));
301                 if (dir_detail->name == NULL) {
302                         printf("\nMemory allocation failed\n");
303                         free(dir_detail);
304                         goto FINISH_OFF;
305                 }
306                 snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i])+1), "%s", pkg_ro_content_rpm[i]);
307                 dir_detail->type = APP2EXT_DIR_RO;
308                 dir_list = g_list_append(dir_list, dir_detail);
309         }
310         if (dir_list) {
311                 list = g_list_first(dir_list);
312                 while (list) {
313                         dir_detail = (app2ext_dir_details *)list->data;
314                         list = g_list_next(list);
315                 }
316         }
317         return dir_list;
318 FINISH_OFF:
319         if (dir_list) {
320                 list = g_list_first(dir_list);
321                 while (list) {
322                         dir_detail = (app2ext_dir_details *)list->data;
323                         if (dir_detail && dir_detail->name) {
324                                 free(dir_detail->name);
325                         }
326                         list = g_list_next(list);
327                 }
328                 g_list_free(dir_list);
329         }
330         return NULL;
331 }
332
333 int _rpm_uninstall_pkg(char *pkgid)
334 {
335         int ret = 0;
336         int err = 0;
337         char buff[256] = {'\0'};
338         pkgmgr_install_location location = 1;
339         int size = -1;
340 #ifdef APP2EXT_ENABLE
341         app2ext_handle *handle = NULL;
342 #endif
343         char *manifest = NULL;
344         pkgmgr_pkginfo_h pkghandle;
345         const char *argv[] = { UNINSTALL_SCRIPT, pkgid, NULL };
346
347 #ifdef APP2EXT_ENABLE
348         ret = pkgmgr_pkginfo_get_pkginfo(pkgid, &pkghandle);
349         if (ret < 0) {
350                 _d_msg(DEBUG_ERR, "Failed to get pkginfo handle\n");
351 //              return RPM_INSTALLER_ERR_INTERNAL;
352         } else {
353                 ret = pkgmgr_pkginfo_get_install_location(pkghandle, &location);
354                 if (ret < 0) {
355                         _d_msg(DEBUG_ERR, "Failed to get install location\n");
356                         pkgmgr_pkginfo_destroy_pkginfo(pkghandle);
357                         return RPM_INSTALLER_ERR_INTERNAL;
358                 }
359                 pkgmgr_pkginfo_destroy_pkginfo(pkghandle);
360                 if (location == PM_INSTALL_LOCATION_PREFER_EXTERNAL) {
361                         handle = app2ext_init(APP2EXT_SD_CARD);
362                         if (handle == NULL) {
363                                 _d_msg(DEBUG_ERR, "app2ext init failed\n");
364                                 return RPM_INSTALLER_ERR_INTERNAL;
365                         }
366                         if ((&(handle->interface) != NULL) && (handle->interface.pre_uninstall != NULL) && (handle->interface.post_uninstall != NULL)){
367                                 ret = app2ext_get_app_location(pkgid);
368                                 if (ret == APP2EXT_INTERNAL_MEM){
369                                                 _d_msg(DEBUG_ERR, "app2xt APP is not in MMC, go internal (%d)\n", ret);
370                                 }
371                                 else {
372                                         ret = handle->interface.pre_uninstall(pkgid);
373                                         if (ret == APP2EXT_ERROR_MMC_STATUS || ret == APP2EXT_SUCCESS ) {
374                                                 _d_msg(DEBUG_ERR, "app2xt MMC is not here, go internal (%d)\n", ret);
375                                         }
376                                         else {
377                                                 _d_msg(DEBUG_ERR, "app2xt pre uninstall API failed (%d)\n", ret);
378                                                 handle->interface.post_uninstall(pkgid);
379                                                 return RPM_INSTALLER_ERR_INTERNAL;
380                                         }
381                                 }
382                         }
383                 }
384         }
385 #endif
386
387 #ifdef PRE_CHECK_FOR_MANIFEST
388         /*Manifest info should be removed first because after installation manifest
389         file is uninstalled. If uninstallation fails, we need to re-insert manifest info for consistency*/
390         manifest = pkgmgr_parser_get_manifest_file(pkgid);
391         if (manifest == NULL) {
392                 _d_msg(DEBUG_ERR, "manifest name is NULL\n");
393                 return RPM_INSTALLER_ERR_INTERNAL;
394         }
395         _d_msg(DEBUG_INFO, "manifest name is %s\n", manifest);
396         pkgmgr_parser_parse_manifest_for_uninstallation(manifest, NULL);
397 #endif
398
399         ret = __rpm_xsystem(argv);
400         if (ret != 0) {
401                 _d_msg(DEBUG_ERR, "uninstall failed with error(%d)\n", ret);
402                 #ifdef PRE_CHECK_FOR_MANIFEST
403                 err = pkgmgr_parser_parse_manifest_for_installation(manifest, NULL);
404                 if (err < 0) {
405                         _d_msg(DEBUG_ERR, "Parsing Manifest Failed\n");
406                 }
407                 if (manifest) {
408                         free(manifest);
409                         manifest = NULL;
410                 }
411                 #endif
412                 #ifdef APP2EXT_ENABLE
413                 if ((handle != NULL) && (handle->interface.post_uninstall != NULL)){
414                         handle->interface.post_uninstall(pkgid);
415                 }
416                 #endif
417                 return ret;
418         }
419
420 #ifdef APP2EXT_ENABLE
421         if ((handle != NULL) && (handle->interface.post_uninstall != NULL)){
422                 handle->interface.post_uninstall(pkgid);
423                 app2ext_deinit(handle);
424         }
425 #endif
426
427 #ifdef PRE_CHECK_FOR_MANIFEST
428         if (manifest) {
429                 free(manifest);
430                 manifest = NULL;
431         }
432 #endif
433         /* Uninstallation Success. Remove the installation time key from vconf*/
434         snprintf(buff, 256, "db/app-info/%s/installed-time", pkgid);
435         err = vconf_unset(buff);
436         if (err) {
437                 _d_msg(DEBUG_ERR, "unset installation time failed\n");
438         }
439         return ret;
440 }
441
442 int _rpm_install_pkg(char *pkgfilepath, char *installoptions)
443 {
444         int err = 0;
445         int ret = 0;
446         time_t cur_time;
447         char buff[256] = {'\0'};
448         char manifest[1024] = { '\0'};
449         char *mfst = NULL;
450         pkgmgrinfo_install_location location = 1;
451         int size = -1;
452 #ifdef APP2EXT_ENABLE
453         app2ext_handle *handle = NULL;
454         GList *dir_list = NULL;
455 #endif
456         pkgmgr_pkginfo_h pkghandle;
457         const char *argv[] = {
458                 INSTALL_SCRIPT, pkgfilepath, installoptions, NULL
459         };
460
461 #ifdef PRE_CHECK_FOR_MANIFEST
462         char cwd[1024] = {'\0'};
463         char query[1024] = {'\0'};
464         int m_exist = 0;
465         getcwd(cwd, 1024);
466         if (cwd[0] == '\0') {
467                 _d_msg(DEBUG_ERR, "getcwd() Failed\n");
468                 return RPM_INSTALLER_ERR_INTERNAL;
469         }
470         _d_msg(DEBUG_ERR, "Current working directory is %s\n", cwd);
471         err = chdir("/tmp");
472         if (err != 0) {
473                 _d_msg(DEBUG_ERR, "chdir() failed\n");
474                 return RPM_INSTALLER_ERR_INTERNAL;
475         }
476         _d_msg(DEBUG_ERR, "Switched to /tmp\n");
477         snprintf(query, 1024, "/usr/bin/rpm2cpio %s | cpio -idmv", pkgfilepath);
478         _d_msg(DEBUG_INFO, "query= %s\n", query);
479         system(query);
480         snprintf(manifest, 1024, "/tmp/opt/share/packages/%s.xml", gpkgname);
481         _d_msg(DEBUG_ERR, "Manifest name is %s\n", manifest);
482         if (access(manifest, F_OK)) {
483                 _d_msg(DEBUG_ERR, "No rw Manifest File Found\n");
484
485                 snprintf(manifest, 1024, "/tmp/usr/share/packages/%s.xml", gpkgname);
486                 _d_msg(DEBUG_ERR, "Manifest ro name is %s\n", manifest);
487
488                 if (access(manifest, F_OK)) {
489                         _d_msg(DEBUG_ERR, "No ro Manifest File Found\n");
490 //                      unlink(manifest);
491 //                      return RPM_INSTALLER_ERR_NO_MANIFEST;
492                 } else
493                         m_exist = 1;
494         } else
495                 m_exist = 1;
496
497         _d_msg(DEBUG_ERR, "Manifest exists\n");
498
499         err = chdir(cwd);
500         if (err != 0) {
501                 _d_msg(DEBUG_ERR, "chdir() failed\n");
502 //              unlink(manifest);
503 //              return RPM_INSTALLER_ERR_INTERNAL;
504         }
505
506         if (m_exist) {
507                 err = pkgmgr_parser_check_manifest_validation(manifest);
508                 if(err < 0) {
509                         _d_msg(DEBUG_ERR, "Invalid manifest\n");
510                         unlink(manifest);
511                         return RPM_INSTALLER_ERR_INVALID_MANIFEST;
512                 }
513         }
514 #endif
515
516 #ifdef APP2EXT_ENABLE
517         ret = pkgmgrinfo_pkginfo_get_location_from_xml(manifest, &location);
518
519         if (ret < 0) {
520                 _d_msg(DEBUG_ERR, "Failed to get install location\n");
521                 return RPM_INSTALLER_ERR_INTERNAL;
522         } else {
523                 if (location == PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL) {
524                         ret = pkgmgrinfo_pkginfo_get_size_from_xml(manifest, &size);
525                         if (ret < 0) {
526                                 _d_msg(DEBUG_ERR, "Failed to get package size\n");
527                                 return RPM_INSTALLER_ERR_INTERNAL;
528                         }
529                 }
530         }
531
532         if ((location == PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL) && size > 0) {
533                 handle = app2ext_init(APP2EXT_SD_CARD);
534                 if (handle == NULL) {
535                         _d_msg(DEBUG_ERR, "app2ext init failed\n");
536                         return RPM_INSTALLER_ERR_INTERNAL;
537                 }
538                 if ((&(handle->interface) != NULL) && (handle->interface.pre_install != NULL) && (handle->interface.post_install != NULL)){
539                         dir_list = __rpm_populate_dir_list();
540                         if (dir_list == NULL) {
541                                 _d_msg(DEBUG_ERR, "\nError in populating the directory list\n");
542                                 app2ext_deinit(handle);
543                                 return RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
544                         }
545                         ret = handle->interface.pre_install(gpkgname, dir_list, size);
546                         if (ret == APP2EXT_ERROR_MMC_STATUS) {
547                                 _d_msg(DEBUG_ERR, "app2xt MMC is not here, go internal\n");
548                         } else if (ret == APP2EXT_SUCCESS){
549                                 _d_msg(DEBUG_ERR, "pre_install done, go internal\n");
550                         }
551                         else {
552                                 _d_msg(DEBUG_ERR, "app2xt pre install API failed (%d)\n", ret);
553                                 __rpm_clear_dir_list(dir_list);
554                                 handle->interface.post_install(gpkgname, APP2EXT_STATUS_FAILED);
555                                 app2ext_deinit(handle);
556                                 return RPM_INSTALLER_ERR_INTERNAL;
557                         }
558                 }
559         }
560 #endif
561
562         err = __rpm_xsystem(argv);
563
564         if (err != 0) {
565                 _d_msg(DEBUG_ERR, "install complete with error(%d)\n", err);
566
567                 #ifdef APP2EXT_ENABLE
568                 if ((handle != NULL) && (handle->interface.post_install != NULL)){
569                         __rpm_clear_dir_list(dir_list);
570                         handle->interface.post_install(gpkgname, APP2EXT_STATUS_FAILED);
571                 }
572                 #endif
573
574                 return err;
575         }
576
577 #ifdef APP2EXT_ENABLE
578         if ((handle != NULL) && (handle->interface.post_install != NULL)){
579                 __rpm_clear_dir_list(dir_list);
580                 handle->interface.post_install(gpkgname, APP2EXT_STATUS_SUCCESS);
581                 app2ext_deinit(handle);
582         }
583 #endif
584
585         /*Parse the manifest to get install location and size. If installation fails, remove manifest info from DB*/
586         err = pkgmgr_parser_parse_manifest_for_installation(manifest, NULL);
587         if (err < 0) {
588                 _d_msg(DEBUG_ERR, "Parsing Manifest Failed\n");
589 //              unlink(manifest);
590 //              return RPM_INSTALLER_ERR_INTERNAL;
591         } else {
592                 _d_msg(DEBUG_ERR, "Parsing Manifest Success\n");
593                 return err;
594         }
595
596 #ifndef PRE_CHECK_FOR_MANIFEST
597         mfst = pkgmgr_parser_get_manifest_file(gpkgname);
598         if (mfst == NULL) {
599                 _d_msg(DEBUG_ERR, "manifest name is NULL\n");
600                 unlink(manifest);
601                 return RPM_INSTALLER_ERR_INTERNAL;
602         }
603         pkgmgr_parser_parse_manifest_for_installation(mfst, NULL);
604         if (mfst) {
605                 free(mfst);
606                 mfst = NULL;
607         }
608 #endif
609         /* Install Success. Store the installation time*/
610         cur_time = time(NULL);
611         snprintf(buff, 256, "db/app-info/%s/installed-time", gpkgname);
612         /* The time is stored in time_t format. It can be converted to
613         local time or GMT time as per the need by the apps*/
614         ret = vconf_set_int(buff, cur_time);
615         if(ret) {
616                 _d_msg(DEBUG_ERR, "setting installation time failed\n");
617                 vconf_unset(buff);
618         }
619         unlink(manifest);
620         return err;
621 }
622
623 int _rpm_upgrade_pkg(char *pkgfilepath, char *installoptions)
624 {
625         int err = 0;
626         int ret = 0;
627         time_t cur_time;
628         char buff[256] = {'\0'};
629         char manifest[1024] = { '\0'};
630         char *mfst = NULL;
631         pkgmgr_install_location location = 1;
632         int size = -1;
633 #ifdef APP2EXT_ENABLE
634         app2ext_handle *handle = NULL;
635         GList *dir_list = NULL;
636 #endif
637         pkgmgr_pkginfo_h pkghandle;
638         const char *argv[] = {
639                 UPGRADE_SCRIPT, pkgfilepath, installoptions, NULL
640         };
641
642 #ifdef PRE_CHECK_FOR_MANIFEST
643         char cwd[1024] = {'\0'};
644         char query[1024] = {'\0'};
645         int m_exist = 0;
646         getcwd(cwd, 1024);
647         if (cwd[0] == '\0') {
648                 _d_msg(DEBUG_ERR, "getcwd() Failed\n");
649                 return RPM_INSTALLER_ERR_INTERNAL;
650         }
651         _d_msg(DEBUG_ERR, "Current working directory is %s\n", cwd);
652         err = chdir("/tmp");
653         if (err != 0) {
654                 _d_msg(DEBUG_ERR, "chdir() failed\n");
655                 return RPM_INSTALLER_ERR_INTERNAL;
656         }
657         _d_msg(DEBUG_ERR, "Switched to /tmp\n");
658         snprintf(query, 1024, "/usr/bin/rpm2cpio %s | cpio -idmv", pkgfilepath);
659         _d_msg(DEBUG_INFO, "query= %s\n", query);
660         system(query);
661         snprintf(manifest, 1024, "/tmp/opt/share/packages/%s.xml", gpkgname);
662         _d_msg(DEBUG_ERR, "Manifest name is %s\n", manifest);
663         if (access(manifest, F_OK)) {
664                 _d_msg(DEBUG_ERR, "No rw Manifest File Found\n");
665
666                 snprintf(manifest, 1024, "/tmp/usr/share/packages/%s.xml", gpkgname);
667                 _d_msg(DEBUG_ERR, "Manifest ro name is %s\n", manifest);
668
669                 if (access(manifest, F_OK)) {
670                         _d_msg(DEBUG_ERR, "No ro Manifest File Found\n");
671 //                      unlink(manifest);
672 //                      return RPM_INSTALLER_ERR_NO_MANIFEST;
673                 } else
674                         m_exist = 1;
675         } else
676                 m_exist = 1;
677
678         _d_msg(DEBUG_ERR, "Manifest exists\n");
679
680         err = chdir(cwd);
681         if (err != 0) {
682                 _d_msg(DEBUG_ERR, "chdir() failed\n");
683 //              unlink(manifest);
684 //              return RPM_INSTALLER_ERR_INTERNAL;
685         }
686
687         if (m_exist) {
688                 err = pkgmgr_parser_check_manifest_validation(manifest);
689                 if(err < 0) {
690                         _d_msg(DEBUG_ERR, "Invalid manifest\n");
691                         unlink(manifest);
692                         return RPM_INSTALLER_ERR_INVALID_MANIFEST;
693                 }
694         }
695         /*Parse the manifest to get install location and size. If upgradation fails, remove manifest info from DB*/
696         err = pkgmgr_parser_parse_manifest_for_upgrade(manifest, NULL);
697         if (err < 0) {
698                 _d_msg(DEBUG_ERR, "Parsing Manifest Failed\n");
699 //              unlink(manifest);
700 //              return RPM_INSTALLER_ERR_INTERNAL;
701         } else {
702                 _d_msg(DEBUG_ERR, "Parsing Manifest Success\n");
703         }
704 #endif
705
706 #ifdef APP2EXT_ENABLE
707         ret = pkgmgr_pkginfo_get_pkginfo(gpkgname, &pkghandle);
708         if (ret < 0) {
709                 _d_msg(DEBUG_ERR, "Failed to get pkginfo handle\n");
710 //              unlink(manifest);
711 //              return RPM_INSTALLER_ERR_INTERNAL;
712         } else {
713                 ret = pkgmgr_pkginfo_get_install_location(pkghandle, &location);
714                 if (ret < 0) {
715                         _d_msg(DEBUG_ERR, "Failed to get install location\n");
716                         pkgmgr_pkginfo_destroy_pkginfo(pkghandle);
717                         unlink(manifest);
718                         return RPM_INSTALLER_ERR_INTERNAL;
719                 } else {
720                         if (location == PM_INSTALL_LOCATION_PREFER_EXTERNAL) {
721                                 ret = pkgmgr_pkginfo_get_package_size(pkghandle, &size);
722                                 if (ret < 0) {
723                                         _d_msg(DEBUG_ERR, "Failed to get package size\n");
724                                         pkgmgr_pkginfo_destroy_pkginfo(pkghandle);
725                                         unlink(manifest);
726                                         return RPM_INSTALLER_ERR_INTERNAL;
727                                 }
728                         }
729                 }
730                 pkgmgr_pkginfo_destroy_pkginfo(pkghandle);
731                 if ((location == PM_INSTALL_LOCATION_PREFER_EXTERNAL) && size > 0) {
732                         handle = app2ext_init(APP2EXT_SD_CARD);
733                         if (handle == NULL) {
734                                 _d_msg(DEBUG_ERR, "app2ext init failed\n");
735                                 unlink(manifest);
736                                 return RPM_INSTALLER_ERR_INTERNAL;
737                         }
738                         if ((&(handle->interface) != NULL) && (handle->interface.pre_upgrade != NULL) && (handle->interface.post_upgrade != NULL)){
739                                 dir_list = __rpm_populate_dir_list();
740                                 if (dir_list == NULL) {
741                                         _d_msg(DEBUG_ERR, "\nError in populating the directory list\n");
742                                         return RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
743                                 }
744                                 ret = handle->interface.pre_upgrade(gpkgname, dir_list, size);
745                                 if (ret == APP2EXT_ERROR_MMC_STATUS || ret == APP2EXT_SUCCESS ) {
746                                         _d_msg(DEBUG_ERR, "app2xt MMC is not here, go internal (%d)\n", ret);
747                                 }
748                                 else {
749                                         _d_msg(DEBUG_ERR, "app2xt pre upgrade API failed (%d)\n", ret);
750                                         __rpm_clear_dir_list(dir_list);
751                                         handle->interface.post_upgrade(gpkgname, APP2EXT_STATUS_FAILED);
752                                         unlink(manifest);
753                                         return RPM_INSTALLER_ERR_INTERNAL;
754                                 }
755                         }
756                 }
757         }
758 #endif
759
760         err = __rpm_xsystem(argv);
761         if (err != 0) {
762                 _d_msg(DEBUG_ERR, "upgrade complete with error(%d)\n", err);
763                 /*remove manifest info*/
764                 #ifdef PRE_CHECK_FOR_MANIFEST
765                 pkgmgr_parser_parse_manifest_for_uninstallation(manifest, NULL);
766                 #endif
767                 #ifdef APP2EXT_ENABLE
768                 if ((handle != NULL) && (handle->interface.post_upgrade != NULL)){
769                         __rpm_clear_dir_list(dir_list);
770                         handle->interface.post_upgrade(gpkgname, APP2EXT_STATUS_FAILED);
771                 }
772                 #endif
773                 unlink(manifest);
774                 return err;
775         }
776 #ifdef APP2EXT_ENABLE
777         if ((handle != NULL) && (handle->interface.post_upgrade != NULL)){
778                 __rpm_clear_dir_list(dir_list);
779                 handle->interface.post_upgrade(gpkgname, APP2EXT_STATUS_SUCCESS);
780                 app2ext_deinit(handle);
781         }
782 #endif
783 #ifndef PRE_CHECK_FOR_MANIFEST
784         mfst = pkgmgr_parser_get_manifest_file(gpkgname);
785         if (mfst == NULL) {
786                 _d_msg(DEBUG_ERR, "manifest name is NULL\n");
787                 unlink(manifest);
788                 return RPM_INSTALLER_ERR_INTERNAL;
789         }
790         pkgmgr_parser_parse_manifest_for_upgrade(mfst, NULL);
791         if (mfst) {
792                 free(mfst);
793                 mfst = NULL;
794         }
795 #endif
796         unlink(manifest);
797         return err;
798 }
799
800 int _rpm_move_pkg(char *pkgid, int move_type)
801 {
802         app2ext_handle *hdl = NULL;
803         int ret = 0;
804         int movetype = -1;
805         GList *dir_list = NULL;
806
807         if (move_type == PM_MOVE_TO_INTERNAL)
808                 movetype = APP2EXT_MOVE_TO_PHONE;
809         else if (move_type == PM_MOVE_TO_SDCARD)
810                 movetype = APP2EXT_MOVE_TO_EXT;
811         else
812                 return RPM_INSTALLER_ERR_WRONG_PARAM;
813
814         hdl = app2ext_init(APP2EXT_SD_CARD);
815         if ((hdl != NULL) && (hdl->interface.move != NULL)){
816                 dir_list = __rpm_move_dir_list();
817                 if (dir_list == NULL) {
818                         _d_msg(DEBUG_ERR, "\nError in populating the directory list\n");
819                         return RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
820                 }
821                 ret = hdl->interface.move(pkgid, dir_list, movetype);
822                 __rpm_clear_dir_list(dir_list);
823                 if (ret != 0) {
824                         _d_msg(DEBUG_ERR, "Failed to move app\n");
825                         return RPM_INSTALLER_ERR_INTERNAL;
826                 }
827                 app2ext_deinit(hdl);
828                 return RPM_INSTALLER_SUCCESS;
829         } else {
830                 _d_msg(DEBUG_ERR,"Failed to get app2ext handle\n");
831                 return RPM_INSTALLER_ERR_INTERNAL;
832         }
833 }
834