4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
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>
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
28 #include <sys/types.h>
36 #include <ctype.h> /* for isspace () */
37 #include <pkgmgr_parser.h>
39 #include "rpm-installer-util.h"
40 #include "rpm-installer.h"
41 #include "rpm-frontend.h"
43 #define PRE_CHECK_FOR_MANIFEST
44 #define INSTALL_SCRIPT "/usr/bin/install_rpm_package.sh"
45 #define UNINSTALL_SCRIPT "/usr/bin/uninstall_rpm_package.sh"
46 #define UPGRADE_SCRIPT "/usr/bin/upgrade_rpm_package.sh"
47 #define RPM2CPIO "/usr/bin/rpm2cpio"
49 enum rpm_request_type {
55 typedef enum rpm_request_type rpm_request_type;
56 extern char *gpkgname;
58 static int __rpm_xsystem(const char *argv[]);
59 static void __rpm_process_line(char *line);
60 static void __rpm_perform_read(int fd);
62 static void __rpm_process_line(char *line)
65 tok = strtok(line, " ");
67 if (!strncmp(tok, "%%", 2)) {
68 tok = strtok(NULL, " ");
70 _d_msg(DEBUG_INFO, "Install percentage is %s\n",
72 _ri_broadcast_status_notification(gpkgname,
75 _ri_stat_cb(gpkgname, "install_percent", tok);
83 static void __rpm_perform_read(int fd)
88 static char buffer[1024] = { 0, };
89 static int buffer_position;
91 size = read(fd, &buffer[buffer_position],
92 sizeof(buffer) - buffer_position);
93 buffer_position += size;
97 /* Process each line of the recieved buffer */
98 buf_ptr = tmp_ptr = buffer;
99 while ((tmp_ptr = (char *)memchr(buf_ptr, '\n',
100 buffer + buffer_position - buf_ptr)) !=
103 __rpm_process_line(buf_ptr);
104 /* move to next line and continue */
105 buf_ptr = tmp_ptr + 1;
108 /*move the remaining bits at the start of the buffer
109 and update the buffer position */
110 buf_ptr = (char *)memrchr(buffer, 0, buffer_position);
114 /* we have processed till the last \n which has now become
115 0x0. So we increase the pointer to next position */
118 memmove(buffer, buf_ptr, buf_ptr - buffer);
119 buffer_position = buffer + buffer_position - buf_ptr;
122 static int __rpm_xsystem(const char *argv[])
129 if (pipe(pipefd) == -1) {
130 _d_msg(DEBUG_ERR, "pipe creation failed\n");
133 /*Read progress info via pipe */
138 _d_msg(DEBUG_ERR, "fork failed\n");
148 if (execvp(argv[0], (char *const *)argv) == -1) {
149 _d_msg(DEBUG_ERR, "execvp failed\n");
160 while ((err = waitpid(pid, &status, WNOHANG)) != pid) {
164 _d_msg(DEBUG_ERR, "waitpid failed\n");
173 FD_SET(pipefd[0], &rfds);
177 pselect(pipefd[0] + 1, &rfds, NULL, NULL, &tv, NULL);
181 else if (select_ret < 0 && errno == EINTR)
183 else if (select_ret < 0) {
184 _d_msg(DEBUG_ERR, "select() returned error\n");
187 if (FD_ISSET(pipefd[0], &rfds))
188 __rpm_perform_read(pipefd[0]);
192 /* Check for an error code. */
193 if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0) {
195 if (WIFSIGNALED(status) != 0 && WTERMSIG(status) == SIGSEGV) {
197 ("Sub-process %s received a segmentation fault. \n",
199 } else if (WIFEXITED(status) != 0) {
200 printf("Sub-process %s returned an error code (%u)\n",
201 argv[0], WEXITSTATUS(status));
203 printf("Sub-process %s exited unexpectedly\n", argv[0]);
206 return WEXITSTATUS(status);
209 int _rpm_uninstall_pkg(char *pkgname)
213 char buff[256] = {'\0'};
214 const char *argv[] = { UNINSTALL_SCRIPT, pkgname, NULL };
216 #ifdef PRE_CHECK_FOR_MANIFEST
217 char *manifest = NULL;
218 manifest = pkgmgr_parser_get_manifest_file(pkgname);
219 if (access(manifest, F_OK)) {
220 _d_msg(DEBUG_ERR, "No Manifest File Found\n");
222 pkgmgr_parser_parse_manifest_for_uninstallation(manifest, NULL);
229 ret = __rpm_xsystem(argv);
231 _d_msg(DEBUG_ERR, "uninstall failed with error(%d)\n", ret);
234 /* Uninstallation Success. Remove the installation time key from vconf*/
235 snprintf(buff, 256, "db/app-info/%s/installed-time", pkgname);
236 err = vconf_unset(buff);
238 _d_msg(DEBUG_ERR, "unset installation time failed\n");
243 int _rpm_install_pkg(char *pkgfilepath, char *installoptions)
248 char buff[256] = {'\0'};
249 const char *argv[] = {
250 INSTALL_SCRIPT, pkgfilepath, installoptions, NULL
252 #ifdef PRE_CHECK_FOR_MANIFEST
253 char cwd[1024] = {'\0'};
254 char query[1024] = {'\0'};
255 char manifest[1024] = { '\0'};
259 _d_msg(DEBUG_ERR, "getcwd() Failed\n");
262 _d_msg(DEBUG_ERR, "Current working directory is %s\n", cwd);
265 _d_msg(DEBUG_ERR, "chdir() failed\n");
268 _d_msg(DEBUG_ERR, "Switched to /tmp\n");
269 snprintf(query, 1024, "/usr/bin/rpm2cpio %s | cpio -idmv", pkgfilepath);
270 _d_msg(DEBUG_INFO, "query= %s\n", query);
272 snprintf(manifest, 1024, "/tmp/opt/share/packages/%s.xml", gpkgname);
273 _d_msg(DEBUG_ERR, "Manifest name is %s\n", manifest);
274 if (access(manifest, F_OK)) {
275 _d_msg(DEBUG_ERR, "No rw Manifest File Found\n");
277 snprintf(manifest, 1024, "/tmp/usr/share/packages/%s.xml", gpkgname);
278 _d_msg(DEBUG_ERR, "Manifest ro name is %s\n", manifest);
280 if (access(manifest, F_OK)) {
281 _d_msg(DEBUG_ERR, "No ro Manifest File Found\n");
287 _d_msg(DEBUG_ERR, "Manifest exists\n");
291 _d_msg(DEBUG_ERR, "chdir() failed\n");
296 err = pkgmgr_parser_check_manifest_validation(manifest);
298 _d_msg(DEBUG_ERR, "Invalid manifest\n");
303 err = __rpm_xsystem(argv);
305 _d_msg(DEBUG_ERR, "install complete with error(%d)\n", err);
309 #ifdef PRE_CHECK_FOR_MANIFEST
311 err = pkgmgr_parser_parse_manifest_for_installation(manifest, NULL);
313 _d_msg(DEBUG_ERR, "Parsing Manifest Failed\n");
315 _d_msg(DEBUG_ERR, "Parsing Manifest Success\n");
318 /* Install Success. Store the installation time*/
319 cur_time = time(NULL);
320 snprintf(buff, 256, "db/app-info/%s/installed-time", gpkgname);
321 /* The time is stored in time_t format. It can be converted to
322 local time or GMT time as per the need by the apps*/
323 ret = vconf_set_int(buff, cur_time);
325 _d_msg(DEBUG_ERR, "setting installation time failed\n");
331 int _rpm_upgrade_pkg(char *pkgfilepath, char *installoptions)
334 const char *argv[] = {
335 UPGRADE_SCRIPT, pkgfilepath, installoptions, NULL
337 #ifdef PRE_CHECK_FOR_MANIFEST
338 char cwd[1024] = {'\0'};
339 char query[1024] = {'\0'};
340 char manifest[1024] = { '\0'};
344 _d_msg(DEBUG_ERR, "getcwd() Failed\n");
347 _d_msg(DEBUG_ERR, "Current working directory is %s\n", cwd);
350 _d_msg(DEBUG_ERR, "chdir() failed\n");
353 _d_msg(DEBUG_ERR, "Switched to /tmp\n");
354 snprintf(query, 1024, "/usr/bin/rpm2cpio %s | cpio -idmv", pkgfilepath);
355 _d_msg(DEBUG_INFO, "query= %s\n", query);
357 snprintf(manifest, 1024, "/tmp/opt/share/packages/%s.xml", gpkgname);
358 _d_msg(DEBUG_ERR, "Manifest name is %s\n", manifest);
359 if (access(manifest, F_OK)) {
360 _d_msg(DEBUG_ERR, "No rw Manifest File Found\n");
362 snprintf(manifest, 1024, "/tmp/usr/share/packages/%s.xml", gpkgname);
363 _d_msg(DEBUG_ERR, "Manifest ro name is %s\n", manifest);
365 if (access(manifest, F_OK)) {
366 _d_msg(DEBUG_ERR, "No ro Manifest File Found\n");
372 _d_msg(DEBUG_ERR, "Manifest exists\n");
376 _d_msg(DEBUG_ERR, "chdir() failed\n");
381 err = pkgmgr_parser_check_manifest_validation(manifest);
383 _d_msg(DEBUG_ERR, "Invalid manifest\n");
388 err = __rpm_xsystem(argv);
390 _d_msg(DEBUG_ERR, "upgrade complete with error(%d)\n", err);
393 #ifdef PRE_CHECK_FOR_MANIFEST
395 err = pkgmgr_parser_parse_manifest_for_upgrade(manifest, NULL);
397 _d_msg(DEBUG_ERR, "Parsing Manifest Failed\n");
399 _d_msg(DEBUG_ERR, "Parsing Manifest Success\n");