Update source from tizen 2.3
[platform/core/base/rpm-installer.git] / frontend / src / rpm-cmdline.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 #include <stdio.h>
24 #include <stdlib.h>
25 #include <getopt.h>
26 #include <pthread.h>
27 #include <stdio.h>
28 #include <pkgmgr_installer.h>
29 #include <security-server.h>
30 #include "rpm-frontend.h"
31 #include "rpm-installer-util.h"
32 #include "rpm-installer.h"
33 #include "coretpk-installer.h"
34
35 #define _FIX_POP_UP_
36 extern struct appdata ad;
37 extern int ret_val;
38 extern pkgmgr_installer *pi;
39 ri_frontend_data front_data;
40 char scrolllabel[256];
41 int move_type;
42 #define BUF_SIZE 1024
43 #define OTP_USR_APPS "/opt/usr/apps"
44
45 static void __ri_show_usage(char **arg);
46 static int __ri_process_request(ri_frontend_cmdline_arg *fdata);
47
48 static void __ri_show_usage(char **arg)
49 {
50
51         int i = 0;
52         char buffer[256];
53         char buff[256] = "";
54         while (arg[i] != NULL) {
55                 snprintf(buffer, 256, "%s %s", buff, arg[i]);
56                 strncpy(buff, buffer, 255);
57                 i++;
58         }
59
60         _LOGD("%s\n", buffer);
61         _LOGD(
62                "\nrpm-backend usage\n   rpm-backend -k <keyid>  <command> <pkgid | pkg_path> [-q] \n\n");
63         _LOGD("<Commands> \n");
64         _LOGD(
65                "\t -i <package file path>         : install package file \n");
66         _LOGD(
67                "\t -k <keyid>                   : key id file \n");
68         _LOGD(
69                "\t -r : (recover). Must ignore specific package name or path \n");
70         _LOGD(
71                "\t -d <package name>            : delete a package with package name \n");
72         _LOGD(
73                "\t -q : (quiet) run in background without any user interaction \n");
74         _LOGD(
75                "\t -s : (smack) apply smack rule and set smack label\n");
76 }
77
78 int _ri_parse_hybrid(int argc, char **argv)
79 {
80         int i = 0;
81
82         if (argv[1] != NULL) {
83                 if (!strcmp(argv[1], "-iv")) {
84                         _LOGE("Hybrid Installation start\n");
85
86                         for (i = 0; i < argc; i++) {
87                                 const char* arg_str = argv[i];
88                                 if (arg_str)
89                                         _LOGE("argv[%d] = [%s]\n", i, arg_str);
90                         }
91
92                         if (_coretpk_installer_request_hybrid(argv[1][1], argv[2], atoi(argv[4])) == 0) {
93                                 return RPM_INSTALLER_SUCCESS;
94                         } else {
95                                 return RPM_INSTALLER_ERR_INTERNAL;
96                         }
97                 } else if (!strcmp(argv[1], "-uv")) {
98                         _LOGE("Hybrid Uninstallation start\n");
99                         return RPM_INSTALLER_SUCCESS;
100                 }
101         }
102
103         return RPM_INSTALLER_ERR_WRONG_PARAM;
104 }
105
106 int _ri_parse_cmdline(int argc, char **argv, ri_frontend_cmdline_arg *data)
107 {
108         int req_cmd = INVALID_CMD;
109         const char *pkgid = NULL;
110         const char *pkeyid = NULL;
111         int ret = 0;
112         int move_type = -1;
113         pi = pkgmgr_installer_new();
114         if (!pi) {
115                 _LOGE(
116                        "Failure in creating the pkgmgr_installer object \n");
117                 return RPM_INSTALLER_ERR_WRONG_PARAM;
118         }
119         ret = pkgmgr_installer_receive_request(pi, argc, argv);
120         if (ret) {
121                 _LOGE("pkgmgr_installer_receive_request failed \n");
122                 return RPM_INSTALLER_ERR_WRONG_PARAM;
123         }
124         ret = pkgmgr_installer_get_request_type(pi);
125         switch (ret) {
126         case PKGMGR_REQ_INSTALL:
127                 req_cmd = INSTALL_CMD;
128                 break;
129         case PKGMGR_REQ_REINSTALL:
130                 req_cmd = CORETPK_REINSTALL_CMD;
131                 break;
132         case PKGMGR_REQ_UNINSTALL:
133                 req_cmd = DELETE_CMD;
134                 break;
135         case PKGMGR_REQ_RECOVER:
136                 req_cmd = RECOVER_CMD;
137                 break;
138         case PKGMGR_REQ_CLEAR:
139                 req_cmd = CLEARDATA_CMD;
140                 break;
141         case PKGMGR_REQ_MOVE:
142                 req_cmd = MOVE_CMD;
143                 break;
144         case PKGMGR_REQ_SMACK:
145                 req_cmd = SMACK_CMD;
146                 break;
147         case PKGMGR_REQ_PERM:
148                 goto PARSEERROR;
149         case PKGMGR_REQ_INVALID:
150                 req_cmd = INVALID_CMD;
151                 goto PARSEERROR;
152         default:
153                 goto PARSEERROR;
154         }
155         if (req_cmd != RECOVER_CMD) {
156                 pkgid = pkgmgr_installer_get_request_info(pi);
157                 if (!pkgid) {
158                         _LOGE(
159                                "pkgmgr_installer_get_request_info failed \n");
160                         return RPM_INSTALLER_ERR_WRONG_PARAM;
161                 }
162                 pkeyid = pkgmgr_installer_get_session_id(pi);
163                 if (!pkeyid) {
164                         _LOGE("pkgmgr_installer_get_session_id failed \n");
165                         return RPM_INSTALLER_ERR_WRONG_PARAM;
166                 }
167                 move_type = pkgmgr_installer_get_move_type(pi);
168         }
169 //Logically dead code,the value of req_cmd never satisfies the condition
170 #if 0
171         if ((req_cmd < INSTALL_CMD) ||(req_cmd > RPM_CMD_MAX)) {
172                 _LOGE("invalid command \n");
173                 goto PARSEERROR;
174         }
175 #endif
176         data->req_cmd = req_cmd;
177         data->pkgid = (char *)pkgid;
178         data->keyid = (char *)pkeyid;
179         data->move_type = move_type;
180         data->clientid = (char *)pkgmgr_installer_get_caller_pkgid(pi);
181
182         return RPM_INSTALLER_SUCCESS;
183
184  PARSEERROR:
185         _LOGE("Error in parsing input parameter\n");
186         __ri_show_usage(argv);
187         return RPM_INSTALLER_ERR_WRONG_PARAM;
188
189 }
190
191 static int __ri_is_core_tpk_app(char *pkgid)
192 {
193         char pkgpath[BUF_SIZE] = {'\0'};
194
195         snprintf(pkgpath, BUF_SIZE, "%s/%s/tizen-manifest.xml", OTP_USR_APPS, pkgid);
196
197         if (access(pkgpath, R_OK) == 0) {
198                 _LOGE("This is a core tpk app.");
199                 return 0;
200         } else {
201                 _LOGE("This is not a core tpk app.");
202                 return -1;
203         }
204 }
205
206 static int __ri_process_request(ri_frontend_cmdline_arg *data)
207 {
208         int ret = 0;
209         if (!data)
210                 return RPM_INSTALLER_ERR_WRONG_PARAM;
211         char *pkgid = NULL;
212         char *keyid = NULL;
213         if (data->req_cmd != RECOVER_CMD) {
214                 pkgid = strdup(data->pkgid);
215                 if (PM_UNLIKELY(pkgid == NULL)) {
216                         _LOGE("strdup failed\n");
217                         return RPM_INSTALLER_ERR_WRONG_PARAM;
218                 }
219                 keyid = strdup(data->keyid);
220                 if (PM_UNLIKELY(keyid == NULL)) {
221                         _LOGE("strdup failed\n");
222                         free(pkgid);
223                         pkgid = NULL;
224                         return RPM_INSTALLER_ERR_WRONG_PARAM;
225                 }
226         }
227
228         if (pkgid == NULL) {
229                 _LOGE("pkgid is null\n");
230                 return -1;
231         }
232
233         switch (data->req_cmd) {
234         case INSTALL_CMD:
235                 _LOGD("rpm-backend -i %s\n", pkgid);
236                 ret = _rpm_backend_interface(keyid, pkgid, "install", data->clientid);
237                 break;
238         case DELETE_CMD:
239                 if (__ri_is_core_tpk_app(pkgid) == 0) {
240                         _LOGD("------------------------------------------------");
241                         _LOGD("uninstallation: tpk, pkgid=[%s]", pkgid);
242                         _LOGD("------------------------------------------------");
243                         ret = _coretpk_backend_interface("coretpk-uninstall", data);
244                 } else {
245                         _LOGD("uninstallation for rpm [%s]", pkgid);
246                         ret = _rpm_backend_interface(keyid, pkgid, "remove", NULL);
247                 }
248                 break;
249         case CLEARDATA_CMD:
250                 _LOGD("rpm-backend -c %s\n", pkgid);
251                 ret = _rpm_backend_interface(keyid, pkgid, "cleardata", NULL);
252                 break;
253         case MOVE_CMD:
254                 if (__ri_is_core_tpk_app(pkgid) == 0) {
255                         _LOGD("coretpk-move %s\n", pkgid);
256                         ret = _coretpk_backend_interface("coretpk-move", data);
257                 } else {
258                         _LOGD("rpm-backend -m %s -t %d\n", pkgid, data->move_type);
259                         move_type = data->move_type;
260                         ret = _rpm_backend_interface(keyid, pkgid, "move", NULL);
261                 }
262                 break;
263         case RECOVER_CMD:
264                 _LOGD("rpm-backend -r \n");
265                 ret = _rpm_backend_interface(keyid, pkgid, "recover", NULL);
266                 break;
267         case SMACK_CMD:
268                 _LOGD("rpm-backend -s %s", pkgid);
269                 ret = _rpm_backend_interface(keyid, pkgid, "smack", NULL);
270                 break;
271         case EFLWGT_INSTALL_CMD:
272                 _LOGD("eflwgt-install %s\n", pkgid);
273                 ret = _rpm_backend_interface(keyid, pkgid, "eflwgt-install", data->clientid);
274                 break;
275         case CORETPK_INSTALL_CMD:
276                 _LOGD("------------------------------------------------");
277                 _LOGD("installation: tpk, arg=[%s]", pkgid);
278                 _LOGD("------------------------------------------------");
279                 ret = _coretpk_backend_interface("coretpk-install", data);
280                 break;
281         case CORETPK_REINSTALL_CMD:
282                 _LOGD("coretpk-reinstall %s\n", pkgid);
283                 ret = _coretpk_backend_interface("coretpk-reinstall", data);
284                 break;
285         case CORETPK_DIRECTORY_INSTALL_CMD:
286                 _LOGD("coretpk-directory_install %s\n", pkgid);
287                 ret = _coretpk_backend_interface("coretpk-directory-install", data);
288                 break;
289         case ENABLE_CMD:
290                 _LOGD("rpm enable %s\n", pkgid);
291                 ret = _rpm_backend_interface(keyid, pkgid, "rpm-enable", NULL);
292                 break;
293         case DISABLE_CMD:
294                 _LOGD("rpm disable %s\n", pkgid);
295                 ret = _rpm_backend_interface(keyid, pkgid, "rpm-disable", NULL);
296                 break;
297         default:
298                 _LOGE("Error Never Come Here as Error is already checked\n");
299         }
300
301         if (keyid) {
302                 free(keyid);
303                 keyid = NULL;
304         }
305         if (pkgid) {
306                 free(pkgid);
307                 pkgid = NULL;
308         }
309
310         return ret;
311 }
312
313 void _ri_stat_cb(const char *pkgid, const char *key, const char *val)
314 {
315
316         if (NULL == pkgid || NULL == key || NULL == val) {
317                 _LOGE("Either pkgid/key/val is NULL\n");
318                 return;         /*TODO: handle error. */
319         }
320
321         char pkgid_modified[PATH_MAX] = {0};
322         char delims[] = "/";
323         char *result = NULL;
324         char *pkgid_tmp = NULL;
325         char *saveptr = NULL;
326
327         memcpy(pkgid_modified, pkgid, strlen(pkgid));
328
329         result = strtok_r(pkgid_modified, delims, &saveptr);
330         while (result != NULL) {
331                 pkgid_tmp = result;
332                 result = strtok_r(NULL, delims, &saveptr);
333         }
334
335         if (strcmp(key, "install_percent") == 0) {
336                 return;
337         } else if (strcmp(key, "error") == 0) {
338                 /* Store the error to be display to the user */
339                 front_data.error = strdup(val);
340         } else if (strcmp(key, "end") == 0) {
341
342                 char requesttype[32];
343                 switch (front_data.args->req_cmd) {
344                 case INSTALL_CMD:
345                         snprintf(requesttype, sizeof(requesttype),
346                                 "installation");
347                         break;
348                 case DELETE_CMD:
349                         snprintf(requesttype, sizeof(requesttype), "deletion");
350                         break;
351                 case CLEARDATA_CMD:
352                         snprintf(requesttype, sizeof(requesttype),
353                                  "clear data");
354                         break;
355                 case MOVE_CMD:
356                         snprintf(requesttype, sizeof(requesttype),
357                                  "move");
358                         break;
359                 default:
360                         snprintf(requesttype, sizeof(requesttype), "recovery");
361                         break;
362                 }
363
364                 if (front_data.error) {
365                         /* Error Happened */
366                         snprintf(scrolllabel, sizeof(scrolllabel),
367                                  "%s :: %s:: %s:: %s", requesttype, pkgid_tmp,
368                                  "error",
369                                  front_data.error);
370                         _LOGE("%s\n", scrolllabel);
371                         ret_val = _ri_string_to_error_no(front_data.error);
372                         _LOGE("%d\n", ret_val);
373
374                 } else {
375                         snprintf(scrolllabel, sizeof(scrolllabel),
376                                  " %s :: %s :: %s", requesttype, pkgid_tmp,
377                                 "success");
378                         _LOGD("%s\n", scrolllabel);
379                         ret_val = 0;
380                 }
381         }
382 }
383
384 int _ri_cmdline_process(ri_frontend_data *data)
385 {
386         int ret = 0;
387         ri_frontend_cmdline_arg *fdata = data->args;
388         /*rpm-installer is invoked by pkgmgr-server hence server should do cookie validation*/
389         ret = __ri_process_request(fdata);
390         if (ret != RPM_INSTALLER_SUCCESS) {
391                 _LOGE("__ri_process_request: Error\n");
392                 return ret;
393         }
394         return RPM_INSTALLER_SUCCESS;
395 }
396
397 int _ri_cmdline_destroy(ri_frontend_data *data)
398 {
399         if (data == NULL)
400                 return 0;
401
402         if (data->security_cookie){
403                 free(data->security_cookie);
404                 data->security_cookie = NULL;
405         }
406
407         return 0;
408
409 }