upload tizen1.0 source
[pkgs/n/native-installer.git] / backend / src / core / nativeinstallertool.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
24
25
26
27 #include <string.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <getopt.h>
31 #include <fcntl.h>
32 #include <dirent.h>
33 #include <unistd.h>
34 #include <ctype.h>
35 #include "nativeinstaller.h"
36 #include<pkgmgr_installer.h>
37
38 #define DEB     "/usr/etc/package-manager/backend/deb"
39
40 char *gptrpkgname = NULL;
41 extern char scrolllabel[256];
42 enum command {
43         INVALID_BACKEND_CMD = 0,
44         INSTALL_BACKEND_CMD = 1,
45         REMOVE_BACKEND_CMD = 2,
46         UPGRADE_BACKEND_CMD = 3,
47         AUDIT_BACKEND_CMD = 4,
48         RECOVER_BACKEND_CMD = 5,
49         CLEAR_BACKEND_CMD = 6
50 };
51
52 enum optionsflags {
53         INVALID_OPTIONS = 0,
54         FORCE_OVERWITE = 1,
55         IGNORE_DEPENDS = 2,
56         UPDATE_AVAIL = 3,
57 };
58
59 struct parsedout_st {
60         int reqcommand;
61         char *preq_cmd_string;
62         char *ppkgname;
63         int forceoverwrite;
64 };
65
66 static int __pkgmgr_show_pkginfo(char *pkgname);
67 static int __uninstall_package(char *pkgname);
68 static int __clear_private_data(char *pkgname);
69 static void __show_usage();
70 static int __native_recovery(int lastbackstate);
71 static inline int __read_proc(const char *path, char *buf, int size);
72 static inline int __find_pid_by_cmdline(const char *dname,
73                                        const char *cmdline, const char *priv);
74 static bool __is_another_instance_running(const char *exepath);
75 int main_of_backend(char *keyid, char *pkgname, char *reqcommand);
76
77 static int __pkgmgr_show_pkginfo(char *pkgname)
78 {
79
80         if (pkgname == NULL)
81                 return NATIVEINSTALLER_ERR_WRONG_PARAM;
82         pkginfo *info = NULL;
83         info = _pkgmgr_get_installed_pkg_info(pkgname);
84         if (info == NULL) {
85                 d_msg_backend(DEBUG_ERR, "(%s) package not exist\n", pkgname);
86         } else {
87                 printf("----------------------------\n");
88                 printf("PackageName\t: %s\n", info->package_name);
89                 printf("Version\t\t: %s\n", info->version);
90                 printf("----------------------------\n");
91         }
92         if (info) {
93                 free(info);
94                 info = NULL;
95         }
96         return 0;
97 }
98
99 static int __uninstall_package(char *pkgname)
100 {
101
102         if (pkgname == NULL)
103                 return NATIVEINSTALLER_ERR_WRONG_PARAM;
104         int ret = 0;
105         ret = _pkgmgr_package_uninstall(pkgname);
106         if (ret == NATIVEINSTALLER_ERR_PACKAGE_NOT_INSTALLED) {
107                 d_msg_backend(DEBUG_ERR, "[__uninstall_package]%s "
108                                                 "not installed\n",
109                               pkgname);
110         } else if (ret != 0) {
111                 d_msg_backend(DEBUG_ERR,
112                               "[__uninstall_package]%s uninstall failed(%d)\n",
113                               pkgname, ret);
114         } else {
115                 d_msg_backend(DEBUG_ERR,
116                       "[__uninstall_package]%s successfully uninstalled\n",
117                               pkgname);
118         }
119         return ret;
120 }
121
122 static int __clear_private_data(char *pkgname)
123 {
124
125         if (pkgname == NULL)
126                 return NATIVEINSTALLER_ERR_WRONG_PARAM;
127         int ret = 0;
128         ret = _pkgmgr_clear_private_data(pkgname);
129         if (ret == NATIVEINSTALLER_SUCCESS) {
130                 d_msg_backend(DEBUG_ERR,
131                 "[__clear_private_data]%s clear data successful\n", pkgname);
132         } else {
133                 d_msg_backend(DEBUG_ERR,
134                 "[__clear_private_data]%s clear data failed(%d)\n", pkgname, ret);
135         }
136         return ret;
137 }
138
139
140 static void __show_usage()
141 {
142         printf
143             ("\nbackend usage\n    backend <keyid> <pkgname> <commands> \n\n");
144         printf("<Commands> \n");
145         printf
146                 ("\tkeyid <pkgname> install       :"
147                 " install package <PackageFile>\n");
148         printf
149                 ("\tkeyid <pkgname> remove      : "
150                 "uninstall package <PackageName>\n");
151         printf
152                 ("\tkeyid dummy recover         :"
153                 " recover the system\n");
154 }
155
156 static int __native_recovery(int lastbackstate)
157 {
158         char *pkgname = NULL;
159         int lastreq;
160         int options;
161
162         pkginfo *ptmp_pkginfo = NULL;
163         bool already_installed = false;
164         int err = 0;
165
166         char *installoptions = NULL;
167
168         d_msg_backend(DEBUG_INFO, "Native Installer recovery Entry \n");
169
170         /* which package it was installing and what was state at that time */
171         _get_last_input_info(&pkgname, &lastreq, &options);
172
173         switch (lastbackstate) {
174         case REQUEST_ACCEPTED:
175                 /* 
176                  * we can restart the last operations 
177                  * once again as request was only accepted
178                  * but nothing had done 
179                  * It will be same as restarting the last request again
180                  */
181                 d_msg_backend(DEBUG_INFO,
182                       "Native Installer recovery REQUEST_ACCEPTED started \n");
183                 switch (lastreq) {
184                 case INSTALL_BACKEND_CMD:
185                         ptmp_pkginfo =
186                     _pkgmgr_get_pkg_info(pkgname, &err, &already_installed);
187                         if (err != 0 || ptmp_pkginfo == NULL) {
188                                 if (ptmp_pkginfo != NULL) {
189                                         free(ptmp_pkginfo);
190                                         ptmp_pkginfo = NULL;
191                                 }
192                                 goto RECOVERYERROR;
193                         }
194
195                         break;
196
197                 case REMOVE_BACKEND_CMD:
198                         ptmp_pkginfo = _pkgmgr_get_installed_pkg_info(pkgname);
199                         if (ptmp_pkginfo == NULL)
200                                 goto RECOVERYERROR;
201                         if (ptmp_pkginfo != NULL) {
202                                 free(ptmp_pkginfo);
203                                 ptmp_pkginfo = NULL;
204                         }
205                         break;
206                 }
207                 d_msg_backend(DEBUG_INFO,
208                               " Native Installer recovery REQUEST_ACCEPTED Ended \n");
209
210                 _set_backend_state_info(GOT_PACKAGE_INFO_SUCCESSFULLY);
211
212         case GOT_PACKAGE_INFO_SUCCESSFULLY:
213                 d_msg_backend(DEBUG_INFO,
214                               " Native Installer recovery "
215                                 "GOT_PACKAGE_INFO_SUCCESSFULLY started \n");
216                 /* 
217                  * Package information is been read successfully
218                  * For Install and upgrade: This means 
219                  *      manifest file has been successfully processed
220                  * For remove: This means 
221                  *      package was already installed.
222                  */
223                 switch (lastreq) {
224                 case INSTALL_BACKEND_CMD:
225                         err = _pkgmgr_dpkg_install_pkg(pkgname, installoptions);
226                         if (err != 0) {
227                                 d_msg_backend(DEBUG_ERR,
228                                               "_pkgmgr_dpkg_install_pkg "
229                                                 "return error(%d)\n",
230                                               err);
231                                 goto RECOVERYERROR;
232                         }
233                         break;
234
235                 case REMOVE_BACKEND_CMD:
236                         err = _pkgmgr_dpkg_uninstall_pkg(pkgname);
237                         if (err != 0) {
238                                 d_msg_backend(DEBUG_ERR,
239                                       "_pkgmgr_dpkg_uninstall_pkg "
240                                         "return error(%d)\n",
241                                               err);
242                                 /* TO DO clean db and menu screen */
243                                 goto RECOVERYERROR;
244                         }
245                         break;
246                 }
247                 d_msg_backend(DEBUG_INFO,
248                               " Native Installer recovery "
249                                 "GOT_PACKAGE_INFO_SUCCESSFULLY ended \n");
250                 _set_backend_state_info(DPKG_REQUEST_COMPLETED);
251
252         case DPKG_REQUEST_COMPLETED:
253                 d_msg_backend(DEBUG_INFO,
254                               " Native Installer recovery "
255                                 "DPKG_REQUEST_COMPLETED started \n");
256
257                 d_msg_backend(DEBUG_INFO,
258                               " Native Installer recovery"
259                                 " DPKG_REQUEST_COMPLETED ended \n");
260
261                 _set_backend_state_info(REQUEST_COMPLETED);
262                 break;
263         default:
264                 /*
265                  * Unknown state
266                  * No need to recover
267                  */
268                 d_msg_backend(DEBUG_INFO,
269                               " Native Installer recovery Default state \n");
270                 break;
271
272         }
273         return 0;
274
275 RECOVERYERROR:
276         d_msg_backend(DEBUG_ERR, "Error in Recovery error number = (%d)\n",
277                       err);
278         return err;
279 }
280
281 static inline int __read_proc(const char *path, char *buf, int size)
282 {
283         int fd;
284         int ret;
285
286         if (buf == NULL || path == NULL)
287                 return -1;
288
289         fd = open(path, O_RDONLY);
290         if (fd < 0)
291                 return -1;
292
293         ret = read(fd, buf, size - 1);
294         if (ret <= 0) {
295                 close(fd);
296                 return -1;
297         } else
298                 buf[ret] = 0;
299
300         close(fd);
301
302         return ret;
303 }
304
305 static inline int __find_pid_by_cmdline(const char *dname,
306                                        const char *cmdline, const char *priv)
307 {
308         int pid = 0;
309         if (strncmp(cmdline, priv, strlen(DEB)) == 0) {
310                 pid = atoi(dname);
311                 if (pid != getpgid(pid))
312                         pid = 0;
313                 if (pid == getpid())
314                         pid = 0;
315         }
316
317         return pid;
318 }
319
320 static bool __is_another_instance_running(const char *exepath)
321 {
322         DIR *dp;
323         struct dirent *dentry;
324         int pid;
325         int ret;
326         char buf[256] = {0,};
327         char buf1[256] = {0,};
328         dp = opendir("/proc");
329         if (dp == NULL) {
330                 return 0;
331         }
332         while ((dentry = readdir(dp)) != NULL) {
333                 if (!isdigit(dentry->d_name[0]))
334                         continue;
335                 snprintf(buf, sizeof(buf), "/proc/%s/cmdline", dentry->d_name);
336                 ret = __read_proc(buf, buf1, sizeof(buf));
337                 if (ret <= 0)
338                         continue;
339                 pid = __find_pid_by_cmdline(dentry->d_name, buf1, exepath);
340                 if (pid > 0) {
341                         closedir(dp);
342                         return 1;
343                 }
344         }
345
346         closedir(dp);
347         return 0;
348
349 }
350
351 /* 
352 *       check if status some other instance is running or not  
353 *       if status file exist then back end exit with reason code
354 *       another instance is in progress
355 *
356 *       We can use a vconf entry for checking whether back end
357 *       is running properly or not
358 *       When we start the back end, we check the value of vconf,
359 *       there are following scenario
360 *       1) Back end start for the first time. It mean this is the
361 *       first time we are calling backend. 
362 *       then ther will not be any vconf entry
363 *       2) Back end was successfully complete the requested operation
364 *       vconf entry will be completed state
365 *       3) Back end had not able to complete the operation and
366 *       some problem occured in installation like segmentation fault,
367 *       Poweroff, low battery.
368 *       vconf entry will be in started state
369 *       Not-init = -1
370 *       completed = 1
371 *       started = 0
372 */
373 /* int main(int argc, char **argv) */
374 int main_of_backend(char *keyid, char *pkgname, char *reqcommand)
375 {
376         int ret = -1;
377         struct parsedout_st pardata = { 0 };
378         int backendstate;
379         _d_msg_init("backend");
380         d_msg_backend(DEBUG_RESULT, "Backend version: %s\n",
381                       NATIVE_INSTALLER_VERSION);
382         if (reqcommand == NULL) {
383                 d_msg_backend(DEBUG_ERR,"reqcommand is NULL\n");
384                 return NATIVEINSTALLER_ERR_WRONG_PARAM;
385         }
386         if (strcmp(reqcommand, "recover") != 0) {
387                 if (keyid == NULL || pkgname == NULL) {
388                         d_msg_backend(DEBUG_ERR,
389                                       " Either keyid/pkgname is NULL\n");
390                         return NATIVEINSTALLER_ERR_WRONG_PARAM;
391                 }
392         }
393
394         if (strcmp(reqcommand, "install") == 0) {
395                 pardata.reqcommand = INSTALL_BACKEND_CMD;
396                 pardata.preq_cmd_string = strdup("install");
397                 if (pardata.preq_cmd_string == NULL) {
398                         d_msg_backend(DEBUG_ERR,
399                                       "strdup failed due to insufficient memory\n");
400                 }
401         } else if (strcmp(reqcommand, "remove") == 0) {
402                 pardata.reqcommand = REMOVE_BACKEND_CMD;
403                 pardata.preq_cmd_string = strdup("uninstall");
404                 if (pardata.preq_cmd_string == NULL) {
405                         d_msg_backend(DEBUG_ERR,
406                                       "strdup failed due to insufficient memory\n");
407                 }
408         } else if (strcmp(reqcommand, "clear") == 0) {
409                 pardata.reqcommand = CLEAR_BACKEND_CMD;
410                 pardata.preq_cmd_string = strdup("clear");
411                 if (pardata.preq_cmd_string == NULL) {
412                         d_msg_backend(DEBUG_ERR,
413                                       "strdup failed due to insufficient memory\n");
414                 }
415         }else if (strcmp(reqcommand, "recover") == 0) {
416                 pardata.reqcommand = RECOVER_BACKEND_CMD;
417                 pardata.preq_cmd_string = strdup("recover");
418                 if (pardata.preq_cmd_string == NULL) {
419                         d_msg_backend(DEBUG_ERR,
420                                       "strdup failed due to insufficient memory\n");
421                 }
422         } else {
423                 d_msg_backend(DEBUG_INFO, "wrong input parameter\n");
424                 d_msg_backend(DEBUG_RESULT, "%d\n",
425                               NATIVEINSTALLER_ERR_WRONG_PARAM);
426                 return NATIVEINSTALLER_ERR_WRONG_PARAM;
427         }
428
429         pardata.ppkgname = pkgname;
430         backendstate = _get_backend_state();
431
432         if (RECOVER_BACKEND_CMD == pardata.reqcommand) {
433                 if (0 == backendstate) {
434                         int lastbackstate;
435
436                         /* check the current state of backend */
437                         lastbackstate = _get_backend_state_info();
438
439                         if (REQUEST_COMPLETED == lastbackstate) {
440                                 d_msg_backend(DEBUG_INFO,
441                                               " Native Installer recovery is in REQUEST_COMPLETED  \n");
442                                 snprintf(scrolllabel, sizeof(scrolllabel), "No Recovery Needed");
443                         } else
444                                 ret = __native_recovery(lastbackstate);
445                                 if(ret == 0)
446                                         snprintf(scrolllabel, sizeof(scrolllabel), "Recovery Success");
447
448                         /* set the backend state as completed */
449                         _set_backend_state(1);
450                 } else {
451                         /* nothing to recover */
452                         d_msg_backend(DEBUG_INFO,
453                                       " Native Installer recovery Nothing need to be done\n");
454                         ret = 0;
455                         snprintf(scrolllabel, sizeof(scrolllabel), "No Recovery Needed");
456                 }
457                 d_msg_backend(DEBUG_RESULT, "%d\n", ret);
458                 return ret;
459         }
460
461         /* Non Recovery case */
462
463         if (0 == backendstate) {
464                 /* back state is in wrong state; 
465                  * either other instance is running 
466                  * or some thing went wrong in last execution of backend 
467                  */
468                 /* if last execution had problem 
469                  * then request is for the same operation again
470                  * then reexecute the same command 
471                  * other wise roll back the old command
472                  */
473                 char *pkgname = NULL;
474                 int lastreq;
475                 int options;
476
477                 /* which package it was installing and 
478                 what was state at that time */
479                 _get_last_input_info(&pkgname, &lastreq, &options);
480
481                 if ((pardata.reqcommand == lastreq) &&
482                     (strcmp(pkgname, pardata.ppkgname) == 0)) {
483                         /* same command is executed for 2nd time */
484                         /* this is same as recover  */
485                         /* call recover */
486                         int lastbackstate;
487
488                         /* check the current state of backend */
489                         lastbackstate = _get_backend_state_info();
490                         /* Publish Notification that backend has started */
491                         _broadcast_status_notification(pardata.ppkgname,
492                                                             "start",
493                                                     pardata.preq_cmd_string);
494                         _broadcast_status_notification(pardata.ppkgname,
495                                                             "command",
496                                                     pardata.preq_cmd_string);
497                         if (REQUEST_COMPLETED == lastbackstate) {
498                                 d_msg_backend(DEBUG_INFO,
499                                               " Native Installer recovery"
500                                               " is in REQUEST_COMPLETED  \n");
501                         } else
502                                 ret = __native_recovery(lastbackstate);
503
504                         d_msg_backend(DEBUG_INFO,
505                                       "Recovery of old instance failed errno: %d\n ",
506                                       ret);
507                         d_msg_backend(DEBUG_RESULT, "%d\n", ret);
508
509                         if (ret != 0) {
510                                 char *errstr = NULL;
511                                 _error_no_to_string(ret, &errstr);
512                                 _broadcast_status_notification(pardata.ppkgname,
513                                                             "error", errstr);
514                                 stat_cb(pardata.ppkgname, "error", errstr);
515                                 _broadcast_status_notification(pardata.ppkgname,
516                                                             "end", "fail");
517                                 stat_cb(pardata.ppkgname, "end", "fail");
518                                 d_msg_backend(DEBUG_ERR,
519                                               "recovery failed with err(%d) (%s)\n",
520                                               ret, errstr);
521                         } else {
522                                 d_msg_backend(DEBUG_INFO,
523                                               "recovery of last request success\n");
524                                 _broadcast_status_notification(pardata.ppkgname,
525                                                             "end", "ok");
526                                 stat_cb(pardata.ppkgname, "end", "ok");
527                         }
528
529                         /* set the backend state as completed */
530                         _set_backend_state(1);
531                 } else {
532                         /* 
533                          * Another Instance may be running 
534                          * Check for it 
535                          */
536                         ret = __is_another_instance_running(DEB);
537                         if (ret == 1) {
538
539                                 if (pardata.ppkgname) {
540                                         _broadcast_status_notification
541                                             (pardata.ppkgname, "error",
542                                              "Another Instance Running");
543                                         stat_cb(pardata.ppkgname, "error",
544                                                 "Another Instance Running");
545                                         _broadcast_status_notification
546                                             (pardata.ppkgname, "end", "fail");
547                                         stat_cb(pardata.ppkgname, "end",
548                                                 "fail");
549                                 } else {
550                                         _broadcast_status_notification(
551                                                                 "unknown",
552                                                                     "error",
553                                                                     "Another Instance Running");
554                                         stat_cb("unknown", "error",
555                                                 "Another Instance Running");
556                                         _broadcast_status_notification(
557                                                                 "unknown",
558                                                                     "end",
559                                                                     "fail");
560                                         stat_cb("unknown", "end", "fail");
561                                 }
562                                 d_msg_backend(DEBUG_INFO,
563                                               "Request Failed as "
564                                               "Another Instance is running \n");
565
566                                 ret = NATIVEINSTALLER_ERR_RESOURCE_BUSY;
567                                 return ret;
568                         }
569
570                 }
571
572         }
573
574         /* set the backend state as started */
575         _set_backend_state(0);
576
577 #ifdef SEND_PKGPATH
578         gptrpkgname = strdup(pardata.ppkgname);
579
580         /* Publish Notification that backend has started */
581         if (pardata.ppkgname)
582                 _broadcast_status_notification(pardata.ppkgname, "start",
583                                             pardata.preq_cmd_string);
584         else
585                 _broadcast_status_notification("unknown", "start",
586                                             pardata.preq_cmd_string);
587 #endif
588
589         _set_backend_state_info(REQUEST_ACCEPTED);
590
591         /* Set the input request info */
592         _save_last_input_info(pardata.ppkgname, pardata.reqcommand,
593                           pardata.forceoverwrite);
594
595         switch (pardata.reqcommand) {
596         case INSTALL_BACKEND_CMD:
597                 {
598                         d_msg_backend(DEBUG_INFO, "[%s] --install %s\n",
599                                       "backend", pardata.ppkgname);
600 #ifdef SEND_PKGPATH
601                         _broadcast_status_notification(pardata.ppkgname,
602                                                  "command",
603                                                     "Install");
604 #endif
605                         if (pardata.forceoverwrite == FORCE_OVERWITE) {
606                                 d_msg_backend(DEBUG_INFO,
607                                               "[%s] --install %s --force-overwrite\n",
608                                               "backend", pardata.ppkgname);
609                                 ret =
610                                     _pkgmgr_package_install(pardata.ppkgname,
611                                                            true,
612                                                            "--force-overwrite");
613                         } else {
614                                 d_msg_backend(DEBUG_INFO, "[%s] --install %s\n",
615                                               "backend", pardata.ppkgname);
616                                 ret =
617                                     _pkgmgr_package_install(pardata.ppkgname,
618                                                            false, NULL);
619                         }
620                         if (ret == NATIVEINSTALLER_ERR_NEED_USER_CONFIRMATION) {
621                                 break;
622                         }
623                         else if (ret == NATIVEINSTALLER_SUCCESS) {
624                                 d_msg_backend(DEBUG_INFO, "install success\n");
625                                 _broadcast_status_notification(pardata.ppkgname,
626                                                                "end", "ok");
627                                 stat_cb(pardata.ppkgname, "end", "ok");
628                                 }
629                         else {
630
631                                 char *errstr = NULL;
632                                 _error_no_to_string(ret, &errstr);
633                                 _broadcast_status_notification(pardata.ppkgname,
634                                                                "error", errstr);
635                                 stat_cb(pardata.ppkgname, "error", errstr);
636                                 _broadcast_status_notification(pardata.ppkgname,
637                                                                "end", "fail");
638                                 sleep(2);
639                                 stat_cb(pardata.ppkgname, "end", "fail");
640                                 d_msg_backend(DEBUG_ERR,
641                                               "install failed with err(%d) (%s)\n",
642                                               ret, errstr);
643                         } 
644                 }
645                 break;
646         case REMOVE_BACKEND_CMD:
647                 {
648                         d_msg_backend(DEBUG_INFO, "[%s] uninstall %s\n",
649                                       "backend", pardata.ppkgname);
650 #ifdef SEND_PKGPATH
651                         _broadcast_status_notification(pardata.ppkgname,
652                                                        "command",
653                                                        "Remove");
654 #endif
655                         ret = __uninstall_package(pardata.ppkgname);
656                         if (ret != 0) {
657                                 char *errstr = NULL;
658                                 _error_no_to_string(ret, &errstr);
659                                 _broadcast_status_notification(pardata.ppkgname,
660                                                             "error", errstr);
661                                 stat_cb(pardata.ppkgname, "error", errstr);
662                                 sleep(2);
663                                 _broadcast_status_notification(pardata.ppkgname,
664                                                             "end", "fail");
665                                 stat_cb(pardata.ppkgname, "end", "fail");
666                                 d_msg_backend(DEBUG_ERR,
667                                               "remove failed with err(%d) (%s)\n",
668                                               ret, errstr);
669                         } else {
670                                 d_msg_backend(DEBUG_INFO, "remove success\n");
671                                 _broadcast_status_notification(pardata.ppkgname,
672                                                                "end", "ok");
673                                 stat_cb(pardata.ppkgname, "end", "ok");
674                         }
675                 }
676                 break;
677         case CLEAR_BACKEND_CMD:
678                 {
679                         d_msg_backend(DEBUG_INFO, "[%s] clear data %s\n",
680                                       "backend", pardata.ppkgname);
681 #ifdef SEND_PKGPATH
682                         _broadcast_status_notification(pardata.ppkgname,
683                                                        "command",
684                                                        "clear");
685 #endif
686                         ret = __clear_private_data(pardata.ppkgname);
687                         if (ret != 0) {
688                                 char *errstr = NULL;
689                                 _error_no_to_string(ret, &errstr);
690                                 _broadcast_status_notification(pardata.ppkgname,
691                                                             "error", errstr);
692                                 stat_cb(pardata.ppkgname, "error", errstr);
693                                 _broadcast_status_notification(pardata.ppkgname,
694                                                             "end", "fail");
695                                 stat_cb(pardata.ppkgname, "end", "fail");
696                                 d_msg_backend(DEBUG_ERR,
697                                               "clear data failed with err(%d) (%s)\n",
698                                               ret, errstr);
699                         } else {
700                                 d_msg_backend(DEBUG_INFO, "clear data success\n");
701                                 _broadcast_status_notification(pardata.ppkgname,
702                                                                "end", "ok");
703                                 stat_cb(pardata.ppkgname, "end", "ok");
704                         }
705                 }
706                 break;
707         default:
708                 {
709                         _broadcast_status_notification("unknown", "command",
710                                                        "unknown");
711                         _broadcast_status_notification("unknown", "error",
712                                                        "not supported");
713                         stat_cb("unknown", "error", "not supported");
714                         _broadcast_status_notification("unknown", 
715                                                        "end", "fail");
716                         stat_cb("unknown", "end", "fail");
717                         d_msg_backend(DEBUG_ERR, "unknown command \n");
718                         __show_usage();
719                         ret = NATIVEINSTALLER_ERR_WRONG_PARAM;
720                 }
721         }
722
723         if (gptrpkgname) {
724                 free(gptrpkgname);
725                 gptrpkgname = NULL;
726         }
727         if (_get_backend_state_info() != DPKG_REQUEST_PENDING) {
728                 
729                 _set_backend_state_info(REQUEST_COMPLETED);
730                 /* set the backend state as completed */
731                 _set_backend_state(1);
732                 d_msg_backend(DEBUG_RESULT, "%d\n", ret);
733                 _d_msg_deinit();
734         }
735
736         
737         return ret;
738 }
739