Update source from tizen 2.3
[platform/core/base/rpm-installer.git] / common / rpm-installer-util.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 <string.h>
24 #include <stdarg.h>
25 #include <sys/wait.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <wait.h>
29 #include <stdio.h>
30 #include <ctype.h>              /* for isspace () */
31 #include <string.h>
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <dirent.h>
37 #include <sys/statvfs.h>
38
39 #include <syslog.h>
40 #include "rpm-installer-util.h"
41
42 int _ri_get_attribute(xmlTextReaderPtr reader, char *attribute, const char **xml_attribute)
43 {
44         if(xml_attribute == NULL){
45                 _LOGE("@xml_attribute is NULL!!");
46                 return -1;
47         }
48         xmlChar *attrib_val = xmlTextReaderGetAttribute(reader,XMLCHAR(attribute));
49         if(attrib_val)
50                 *xml_attribute = ASCII(attrib_val);
51
52         return 0;
53 }
54
55 void _ri_error_no_to_string(int errnumber, char **errstr)
56 {
57         if (errstr == NULL)
58                 return;
59         switch (errnumber) {
60         case RPM_INSTALLER_SUCCESS:
61                 *errstr = RPM_INSTALLER_SUCCESS_STR;
62                 break;
63         case RPM_INSTALLER_ERR_WRONG_PARAM:
64                 *errstr = RPM_INSTALLER_ERR_WRONG_PARAM_STR;
65                 break;
66         case RPM_INSTALLER_ERR_DBUS_PROBLEM:
67                 *errstr = RPM_INSTALLER_ERR_DBUS_PROBLEM_STR;
68                 break;
69         case RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY:
70                 *errstr = RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY_STR;
71                 break;
72         case RPM_INSTALLER_ERR_PACKAGE_EXIST:
73                 *errstr = RPM_INSTALLER_ERR_PACKAGE_EXIST_STR;
74                 break;
75         case RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED:
76                 *errstr = RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED_STR;
77                 break;
78         case RPM_INSTALLER_ERR_RESOURCE_BUSY:
79                 *errstr = RPM_INSTALLER_ERR_RESOURCE_BUSY_STR;
80                 break;
81         case RPM_INSTALLER_ERR_UNKNOWN:
82                 *errstr = RPM_INSTALLER_ERR_UNKNOWN_STR;
83                 break;
84         case RPM_INSTALLER_ERR_PKG_NOT_FOUND:
85                 *errstr = RPM_INSTALLER_ERR_PKG_NOT_FOUND_STR;
86                 break;
87         case RPM_INSTALLER_ERR_NOT_SUPPOTED_VERSION:
88                 *errstr = RPM_INSTALLER_ERR_NOT_SUPPOTED_VERSION_STR;
89                 break;
90         case RPM_INSTALLER_ERR_NO_RPM_FILE:
91                 *errstr = RPM_INSTALLER_ERR_NO_RPM_FILE_STR;
92                 break;
93         case RPM_INSTALLER_ERR_DB_ACCESS_FAILED:
94                 *errstr = RPM_INSTALLER_ERR_DB_ACCESS_FAILED_STR;
95                 break;
96         case RPM_INSTALLER_ERR_RPM_OPERATION_FAILED:
97                 *errstr = RPM_INSTALLER_ERR_RPM_OPERATION_FAILED_STR;
98                 break;
99         case RPM_INSTALLER_ERR_PACKAGE_NOT_UPGRADED:
100                 *errstr = RPM_INSTALLER_ERR_PACKAGE_NOT_UPGRADED_STR;
101                 break;
102         case RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS:
103                 *errstr = RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS_STR;
104                 break;
105         case RPM_INSTALLER_ERR_PACKAGE_INSTALLATION_DISABLED:
106                 *errstr = RPM_INSTALLER_ERR_PACKAGE_INSTALLATION_DISABLED_STR;
107                 break;
108         case RPM_INSTALLER_ERR_PACKAGE_UNINSTALLATION_DISABLED:
109                 *errstr = RPM_INSTALLER_ERR_PACKAGE_UNINSTALLATION_DISABLED_STR;
110                 break;
111         case RPM_INSTALLER_ERR_CLEAR_DATA_FAILED:
112                 *errstr = RPM_INSTALLER_ERR_CLEAR_DATA_FAILED_STR;
113                 break;
114         case RPM_INSTALLER_ERR_INTERNAL:
115                 *errstr = RPM_INSTALLER_ERR_INTERNAL_STR;
116                 break;
117         case RPM_INSTALLER_ERR_NO_MANIFEST:
118                 *errstr = RPM_INSTALLER_ERR_NO_MANIFEST_STR;
119                 break;
120         case RPM_INSTALLER_ERR_INVALID_MANIFEST:
121                 *errstr = RPM_INSTALLER_ERR_INVALID_MANIFEST_STR;
122                 break;
123         case RPM_INSTALLER_ERR_SIG_NOT_FOUND:
124                 *errstr = RPM_INSTALLER_ERR_SIG_NOT_FOUND_STR;
125                 break;
126         case RPM_INSTALLER_ERR_SIG_INVALID:
127                 *errstr = RPM_INSTALLER_ERR_SIG_INVALID_STR;
128                 break;
129         case RPM_INSTALLER_ERR_SIG_VERIFICATION_FAILED:
130                 *errstr = RPM_INSTALLER_ERR_SIG_VERIFICATION_FAILED_STR;
131                 break;
132         case RPM_INSTALLER_ERR_ROOT_CERT_NOT_FOUND:
133                 *errstr = RPM_INSTALLER_ERR_ROOT_CERT_NOT_FOUND_STR;
134                 break;
135         case RPM_INSTALLER_ERR_CERT_INVALID:
136                 *errstr = RPM_INSTALLER_ERR_CERT_INVALID_STR;
137                 break;
138         case RPM_INSTALLER_ERR_CERTCHAIN_VERIFICATION_FAILED:
139                 *errstr = RPM_INSTALLER_ERR_CERTCHAIN_VERIFICATION_FAILED_STR;
140                 break;
141         case RPM_INSTALLER_ERR_NO_CONFIG:
142                 *errstr = RPM_INSTALLER_ERR_NO_CONFIG_STR;
143                 break;
144         case RPM_INSTALLER_ERR_INVALID_CONFIG:
145                 *errstr = RPM_INSTALLER_ERR_INVALID_CONFIG_STR;
146                 break;
147         case RPM_INSTALLER_ERR_CMD_NOT_SUPPORTED:
148                 *errstr = RPM_INSTALLER_ERR_CMD_NOT_SUPPORTED_STR;
149                 break;
150         default:
151                 *errstr = RPM_INSTALLER_ERR_UNKNOWN_STR;
152                 break;
153         }
154 }
155
156 int _ri_string_to_error_no(char *errstr)
157 {
158         int errnumber = RPM_INSTALLER_ERR_UNKNOWN;
159         if (errstr == NULL)
160                 return errnumber;
161
162         if (strcmp(errstr, RPM_INSTALLER_SUCCESS_STR) == 0)
163                 errnumber = RPM_INSTALLER_SUCCESS;
164         else if (strcmp(errstr, RPM_INSTALLER_ERR_WRONG_PARAM_STR) == 0)
165                 errnumber = RPM_INSTALLER_ERR_WRONG_PARAM;
166         else if (strcmp(errstr, RPM_INSTALLER_ERR_DBUS_PROBLEM_STR) == 0)
167                 errnumber = RPM_INSTALLER_ERR_DBUS_PROBLEM;
168         else if (strcmp(errstr, RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY_STR) == 0)
169                 errnumber = RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY;
170         else if (strcmp(errstr, RPM_INSTALLER_ERR_PACKAGE_EXIST_STR) == 0)
171                 errnumber = RPM_INSTALLER_ERR_PACKAGE_EXIST;
172         else if (strcmp(errstr, RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED_STR)
173                  == 0)
174                 errnumber = RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED;
175         else if (strcmp(errstr, RPM_INSTALLER_ERR_RESOURCE_BUSY_STR) == 0)
176                 errnumber = RPM_INSTALLER_ERR_RESOURCE_BUSY;
177         else if (strcmp(errstr, RPM_INSTALLER_ERR_UNKNOWN_STR) == 0)
178                 errnumber = RPM_INSTALLER_ERR_UNKNOWN;
179         else if (strcmp(errstr, RPM_INSTALLER_ERR_PKG_NOT_FOUND_STR) == 0)
180                 errnumber = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
181         else if (strcmp(errstr, RPM_INSTALLER_ERR_NOT_SUPPOTED_VERSION_STR) ==
182                  0)
183                 errnumber = RPM_INSTALLER_ERR_NOT_SUPPOTED_VERSION;
184         else if (strcmp(errstr, RPM_INSTALLER_ERR_NO_RPM_FILE_STR) == 0)
185                 errnumber = RPM_INSTALLER_ERR_NO_RPM_FILE;
186         else if (strcmp(errstr, RPM_INSTALLER_ERR_DB_ACCESS_FAILED_STR) == 0)
187                 errnumber = RPM_INSTALLER_ERR_DB_ACCESS_FAILED;
188         else if (strcmp(errstr, RPM_INSTALLER_ERR_RPM_OPERATION_FAILED_STR)
189                  == 0)
190                 errnumber = RPM_INSTALLER_ERR_RPM_OPERATION_FAILED;
191         else if (strcmp(errstr, RPM_INSTALLER_ERR_PACKAGE_NOT_UPGRADED_STR) ==
192                  0)
193                 errnumber = RPM_INSTALLER_ERR_PACKAGE_NOT_UPGRADED;
194         else if (strcmp(errstr, RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS_STR) ==
195                  0)
196                 errnumber = RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
197         else if (strcmp(errstr, RPM_INSTALLER_ERR_PACKAGE_INSTALLATION_DISABLED_STR) == 0)
198                 errnumber = RPM_INSTALLER_ERR_PACKAGE_INSTALLATION_DISABLED;
199         else if (strcmp(errstr, RPM_INSTALLER_ERR_PACKAGE_UNINSTALLATION_DISABLED_STR) == 0)
200                 errnumber = RPM_INSTALLER_ERR_PACKAGE_UNINSTALLATION_DISABLED;
201         else if (strcmp(errstr, RPM_INSTALLER_ERR_CLEAR_DATA_FAILED_STR) == 0)
202                 errnumber = RPM_INSTALLER_ERR_CLEAR_DATA_FAILED;
203         else if (strcmp(errstr, RPM_INSTALLER_ERR_INTERNAL_STR) == 0)
204                 errnumber = RPM_INSTALLER_ERR_INTERNAL;
205         else if (strcmp(errstr, RPM_INSTALLER_ERR_NO_MANIFEST_STR) == 0)
206                 errnumber = RPM_INSTALLER_ERR_NO_MANIFEST;
207         else if (strcmp(errstr, RPM_INSTALLER_ERR_INVALID_MANIFEST_STR) == 0)
208                 errnumber = RPM_INSTALLER_ERR_INVALID_MANIFEST;
209         else if (strcmp(errstr, RPM_INSTALLER_ERR_SIG_NOT_FOUND_STR) == 0)
210                 errnumber = RPM_INSTALLER_ERR_SIG_NOT_FOUND;
211         else if (strcmp(errstr, RPM_INSTALLER_ERR_SIG_INVALID_STR) == 0)
212                 errnumber = RPM_INSTALLER_ERR_SIG_INVALID;
213         else if (strcmp(errstr, RPM_INSTALLER_ERR_SIG_VERIFICATION_FAILED_STR) == 0)
214                 errnumber = RPM_INSTALLER_ERR_SIG_VERIFICATION_FAILED;
215         else if (strcmp(errstr, RPM_INSTALLER_ERR_ROOT_CERT_NOT_FOUND_STR) == 0)
216                 errnumber = RPM_INSTALLER_ERR_ROOT_CERT_NOT_FOUND;
217         else if (strcmp(errstr, RPM_INSTALLER_ERR_CERT_INVALID_STR) == 0)
218                 errnumber = RPM_INSTALLER_ERR_CERT_INVALID;
219         else if (strcmp(errstr, RPM_INSTALLER_ERR_CERTCHAIN_VERIFICATION_FAILED_STR) == 0)
220                 errnumber = RPM_INSTALLER_ERR_CERTCHAIN_VERIFICATION_FAILED;
221         else if (strcmp(errstr, RPM_INSTALLER_ERR_NO_CONFIG_STR) == 0)
222                 errnumber = RPM_INSTALLER_ERR_NO_CONFIG;
223         else if (strcmp(errstr, RPM_INSTALLER_ERR_INVALID_CONFIG_STR) == 0)
224                 errnumber = RPM_INSTALLER_ERR_INVALID_CONFIG;
225         else
226                 errnumber = RPM_INSTALLER_ERR_UNKNOWN;
227
228         return errnumber;
229 }
230
231 int _rpm_delete_dir(char *dirname)
232 {
233         int ret = 0;
234         DIR *dp;
235         struct dirent *ep;
236         char abs_filename[FILENAME_MAX];
237         struct stat stFileInfo;
238
239         if (dirname == NULL) {
240                 _LOGE("dirname is NULL.");
241                 return -1;
242         }
243
244         _LOGD("delete_dir=[%s]", dirname);
245
246         dp = opendir(dirname);
247         if (dp != NULL) {
248                 while ((ep = readdir(dp))) {
249                         snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname, ep->d_name);
250                         if (lstat(abs_filename, &stFileInfo) < 0) {
251                                 _LOGE("lstat(%s) failed.", abs_filename);
252                                 perror(abs_filename);
253                         }
254
255                         if (S_ISDIR(stFileInfo.st_mode)) {
256                                 if (strcmp(ep->d_name, ".") && strcmp(ep->d_name, "..")) {
257                                         _rpm_delete_dir(abs_filename);
258                                         (void)remove(abs_filename);
259                                 }
260                         } else {
261                                 (void)remove(abs_filename);
262                         }
263                 }
264                 (void)closedir(dp);
265         } else {
266                 _LOGE("opendir(%s) failed.", dirname);
267                 return -1;
268         }
269
270         ret = remove(dirname);
271         if (ret < 0)
272                 _LOGE("remove(%s) failed.", dirname);
273
274         return 0;
275 }
276
277 char* _manifest_to_package(const char* manifest)
278 {
279         char *package;
280
281         if(manifest == NULL) {
282                 _LOGE("manifest is NULL.\n");
283                 return NULL;
284         }
285
286         package = strdup(manifest);
287         if(package == NULL) {
288                 _LOGE("strdup failed.\n");
289                 return NULL;
290         }
291
292         if (!strstr(package, ".xml")) {
293                 _LOGE("%s is not a manifest file\n", manifest);
294                 free(package);
295                 return NULL;
296         }
297
298         return package;
299 }
300
301 /* Extract the basename from the file's path */
302 char *_ri_basename(char *name)
303 {
304         int length;
305         length = name ? strlen(name) : 0;
306         if (!length)
307                 return ".";
308
309         while (--length > 0 && name[length] != '/');
310
311         return length <= 0 ? name : name + length + (name[length] == '/');
312 }
313
314 int _child_element(xmlTextReaderPtr reader, int depth)
315 {
316         int ret = xmlTextReaderRead(reader);
317         int cur = xmlTextReaderDepth(reader);
318         while (ret == 1) {
319
320                 switch (xmlTextReaderNodeType(reader)) {
321                         case XML_READER_TYPE_ELEMENT:
322                                 if (cur == depth + 1)
323                                         return 1;
324                                 break;
325                         case XML_READER_TYPE_TEXT:
326                                 /*text is handled by each function separately*/
327                                 if (cur == depth + 1)
328                                         return 0;
329                                 break;
330                         case XML_READER_TYPE_END_ELEMENT:
331                                 if (cur == depth)
332                                         return 0;
333                                 break;
334                         default:
335                                 if (cur <= depth)
336                                         return 0;
337                                 break;
338                         }
339
340                 ret = xmlTextReaderRead(reader);
341                 cur = xmlTextReaderDepth(reader);
342         }
343         return ret;
344 }
345
346 /*
347 This Function get the package name from the rpm file's path..
348 */
349 int  _get_pkgname_from_rpm_name(char * pkgfile, char **rpm_name){
350
351         char* rpm_file = NULL;
352         char  name[PATH_MAX] = {0};
353         char  temp[PATH_MAX]={0};
354         char *saveptr = NULL;;
355         char *str= NULL;
356         char c ;
357         int ret = RPM_INSTALLER_SUCCESS;
358
359         if(pkgfile == NULL || rpm_name == NULL){
360                 _LOGE("Invalid Parameter!!");
361                 return RPM_INSTALLER_ERR_WRONG_PARAM;
362
363         }
364         _LOGD("RPM path is [%s]",pkgfile);
365
366         /* Get the rpm name from rpm file's path */
367         rpm_file = _ri_basename(pkgfile);
368         _LOGD("RPM name is [%s]",rpm_file);
369
370         strncpy(name,rpm_file,strlen(rpm_file));
371         str = strtok_r(name, "-", &saveptr);
372         if(rpm_file[strlen(name)] != '\0'){
373                 c = rpm_file[strlen(name) + 1];
374         }else{
375                 if(strstr(name,".rpm")){
376                         name[strlen(name)-strlen(".rpm")]='\0';
377                 }
378                 *rpm_name = strdup(name);
379                 if(*rpm_name == NULL){
380                         _LOGE("Malloc failed!!");
381                         ret = RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY;
382                 }
383                 goto end;
384         }
385
386         while(!isdigit(c)){
387                 memset(temp,'\0',PATH_MAX);
388                 str = strtok_r(NULL, "-", &saveptr);
389                 snprintf(temp,PATH_MAX,"-%s",str);
390                 strncat(name,temp,strlen(temp));
391                 if(rpm_file[strlen(name)] != '\0'){
392                         c = rpm_file[strlen(name) + 1];
393                 }else{
394                         break;
395                 }
396         }
397         if(strstr(name,".rpm")){
398                 name[strlen(name)-strlen(".rpm")]='\0';
399         }
400         *rpm_name = strdup(name);
401         if(*rpm_name == NULL){
402                 _LOGE("Malloc failed!!");
403                 ret = RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY;
404         }
405
406 end:
407         return ret;
408
409 }
410
411 /*
412 This Function reads the package field from the xml file.
413 */
414 int  _get_package_name_from_xml(char* manifest, char** pkgname){
415
416         const char *val = NULL;
417         const xmlChar *node;
418         xmlTextReaderPtr reader;
419         int ret = PMINFO_R_OK;
420
421         if(manifest == NULL) {
422                 _LOGE("Input argument is NULL\n");
423                 return PMINFO_R_ERROR;
424         }
425
426         if(pkgname == NULL) {
427                 _LOGE("Argument supplied to hold return value is NULL\n");
428                 return PMINFO_R_ERROR;
429         }
430
431         reader = xmlReaderForFile(manifest, NULL, 0);
432
433         if (reader){
434                 if ( _child_element(reader, -1)) {
435                         node = xmlTextReaderConstName(reader);
436                         if (!node) {
437                                 _LOGE("xmlTextReaderConstName value is NULL\n");
438                                 ret =  PMINFO_R_ERROR;
439                                 goto end;
440                         }
441
442                         if (!strcmp(ASCII(node), "manifest")) {
443                                 ret = _ri_get_attribute(reader,"package",&val);
444                                 if(ret != 0){
445                                         _LOGE("@Error in getting attribute value");
446                                         ret = PMINFO_R_ERROR;
447                                         goto end;
448                                 }
449
450                                 if(val){
451                                         *pkgname = strdup(val);
452                                         if(*pkgname == NULL){
453                                                 _LOGE("Malloc Failed!!");
454                                                 ret = PMINFO_R_ERROR;
455                                                 goto end;
456                                         }
457                                 }
458                         } else {
459                                 _LOGE("Unable to create xml reader\n");
460                                 ret =  PMINFO_R_ERROR;
461                         }
462                 }
463         } else {
464                 _LOGE("xmlReaderForFile value is NULL\n");
465                 return PMINFO_R_ERROR;
466         }
467
468 end:
469         xmlFreeTextReader(reader);
470
471         if(val)
472                 free((void*)val);
473
474         return ret;
475 }
476
477 int _ri_recursive_delete_dir(char *dirname)
478 {
479         int ret=0;
480         DIR *dp;
481         struct dirent *ep;
482         char abs_filename[FILENAME_MAX];
483         struct stat stFileInfo;
484         dp = opendir(dirname);
485         if (dp != NULL) {
486                 while ((ep = readdir(dp))) {
487                         snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
488                                  ep->d_name);
489                         if (lstat(abs_filename, &stFileInfo) < 0)
490                                 perror(abs_filename);
491                         if (S_ISDIR(stFileInfo.st_mode)) {
492                                 if (strcmp(ep->d_name, ".") &&
493                                     strcmp(ep->d_name, "..")) {
494                                         ret=_ri_recursive_delete_dir(abs_filename);
495                                         if(ret < 0)
496                                                 _LOGE("_ri_recursive_delete_dir fail\n");
497
498                                         ret=remove(abs_filename);
499                                         if(ret < 0)
500                                                 _LOGE("remove fail\n");
501                                 }
502                         } else {
503                                 ret = remove(abs_filename);
504                                 if(ret < 0)
505                                         _LOGE("Couldn't remove abs_filename\n");
506                         }
507                 }
508                 (void)closedir(dp);
509         } else {
510                 _LOGE("Couldn't open the directory\n");
511                 if (errno == ENOENT)
512                         return RPM_INSTALLER_SUCCESS;
513                 else
514                         return RPM_INSTALLER_ERR_CLEAR_DATA_FAILED;
515         }
516
517         return RPM_INSTALLER_SUCCESS;
518 }
519
520  int _ri_xsystem(const char *argv[])
521 {
522         int status = 0;
523         pid_t pid;
524         pid = fork();
525         switch (pid) {
526         case -1:
527                 perror("fork failed");
528                 return -1;
529         case 0:
530                 /* child */
531                 execvp(argv[0], (char *const *)argv);
532                 _exit(-1);
533         default:
534                 /* parent */
535                 break;
536         }
537         if (waitpid(pid, &status, 0) == -1) {
538                 perror("waitpid failed");
539                 return -1;
540         }
541         if (WIFSIGNALED(status)) {
542                 perror("signal");
543                 return -1;
544         }
545         if (!WIFEXITED(status)) {
546                 /* shouldn't happen */
547                 perror("should not happen");
548                 return -1;
549         }
550         return WEXITSTATUS(status);
551 }
552 void _ri_remove_wgt_unzip_dir()
553 {
554         if (!access(DIR_RPM_INSTALLER_APPLICATIONS_TEMP, F_OK)) {
555                 _ri_recursive_delete_dir(DIR_RPM_INSTALLER_APPLICATIONS_TEMP);
556                 (void)remove(DIR_RPM_INSTALLER_APPLICATIONS_TEMP);
557         }
558
559 }
560
561 int _ri_get_available_free_memory(const char *opt_path, unsigned long *free_mem)
562 {
563         struct statvfs buf;
564         int ret = 0;
565         if (opt_path == NULL || free_mem == NULL) {
566                 _LOGE("Invalid input parameter\n");
567                 return -1;
568         }
569         memset((void *)&buf, '\0', sizeof(struct statvfs));
570         ret = statvfs(opt_path, &buf);
571         if (ret) {
572                 _LOGE("Unable to get /opt/usr memory information\n");
573                 return -1;
574         }
575         *free_mem = (buf.f_bfree * buf.f_bsize)/SIZE_KB;
576         return 0;
577 }
578
579
580 unsigned long  _ri_calculate_file_size(const char *filename)
581 {
582         struct stat stFileInfo;
583
584         if (stat(filename, &stFileInfo) < 0) {
585                 perror(filename);
586                 return 0;
587         } else
588                 return (stFileInfo.st_size/SIZE_KB);
589 }
590
591 void _ri_process_config_node(xmlTextReaderPtr reader, pkginfo * info)
592 {
593         const xmlChar *node;
594         const char *pkgid = NULL;
595         const char *version = NULL;
596         node = xmlTextReaderConstName(reader);
597         if (node == NULL) {
598                 return;
599         }
600         if (strcmp(ASCII(node), "widget") == 0) {
601                 if (xmlTextReaderNodeType(reader) == 1) {
602                         if(_ri_get_attribute(reader,"version",&version) != 0){
603                                 _LOGE("@Error while getting the attribute value");
604                                 return;
605                         }
606                                 snprintf(info->version, VERSION_MAX_LEN - 1, "%s", version);
607                                 _LOGD("<version> %s", info->version);
608                 }
609         }
610
611
612         if (strcmp(ASCII(node), "tizen:application") == 0) {
613                 if (xmlTextReaderNodeType(reader) == 1) {
614                         if(_ri_get_attribute(reader,"package",&pkgid) != 0){
615                                 _LOGE("@Error while getting the attribute value");
616                                 return;
617                         }
618                         snprintf(info->package_name, PKG_MAX_LEN - 1, "%s", pkgid);
619                         _LOGD("<package> %s", info->package_name);
620                 }
621         }
622         if(pkgid){
623                 free((void*)pkgid);
624                 pkgid = NULL;
625         }
626
627         if(version){
628                 free((void*)version);
629                 version = NULL;
630         }
631         return;
632
633 }
634
635 int  _ri_stream_config_file(const char* filename, pkginfo *info)
636 {
637         xmlTextReaderPtr reader;
638         int ret = RPM_INSTALLER_SUCCESS;
639
640         _LOGD("Reading config file [%s]",filename);
641         reader = xmlReaderForFile(filename,NULL,0);
642         if (reader != NULL) {
643                 ret = xmlTextReaderRead(reader);
644                 while (ret == 1) {
645                         _ri_process_config_node(reader, info);
646                         ret = xmlTextReaderRead(reader);
647                 }
648                 xmlFreeTextReader(reader);
649                 if (ret != 0) {
650                         _LOGE("%s : failed to parse\n", filename);
651                         ret = RPM_INSTALLER_ERR_INTERNAL;
652                 }
653         } else {
654                 _LOGE("Unable to open %s\n", filename);
655                 ret = RPM_INSTALLER_ERR_INTERNAL;
656         }
657         return ret;
658 }
659
660 unsigned long  _ri_calculate_rpm_size( char* rpm_file)
661 {
662         Header  hdr = NULL;
663         rpmts   ts;
664         rpmtd   td;
665         FD_t    fd;
666         rpmRC   rc;
667         rpmVSFlags vsflags = 0;
668         unsigned long  size = 0;
669
670         /* Initialize rpm */
671         rc = rpmReadConfigFiles(NULL,NULL);
672         if( rc != RPMRC_OK){
673                 _LOGE("\n failed to read RPM configuration files");
674                 return size;
675         }
676         /* Open the rpm file */
677         fd = Fopen(rpm_file, "r.ufdio");
678         if ((!fd) || Ferror(fd)){
679                 _LOGE("\n failed to open %s package file",rpm_file);
680                 if(fd)
681                         Fclose(fd);
682                 return size ;
683         }
684
685         hdr = headerNew();
686         ts = rpmtsCreate();
687         td = rpmtdNew();
688         vsflags |= _RPMVSF_NODIGESTS;
689         vsflags |= _RPMVSF_NOSIGNATURES;
690         vsflags |= RPMVSF_NOHDRCHK;
691         (void)rpmtsSetVSFlags(ts, vsflags);
692
693         rc = rpmReadPackageFile(ts,fd,rpm_file,&hdr);
694         if(rc != RPMRC_OK){
695                 _LOGE("\n Couldn't read rpm package file");
696                 size = 0;
697                 Fclose(fd);
698                 goto err;
699         }
700         headerGet(hdr,RPMTAG_SIZE,td,HEADERGET_MINMEM);
701         size = rpmtdGetNumber(td);
702
703         err:
704         rpmtdFreeData(td);
705         rpmtdFree(td);
706         headerFree(hdr);
707         rpmtsFree(ts);
708
709         return size;
710 }
711
712 unsigned long  _ri_calculate_dir_size(const char *dirname)
713 {
714         static unsigned long  total = 0;
715         unsigned long  size = 0;
716         DIR *dp = NULL;
717         struct dirent *ep = NULL;
718         char abs_filename[FILENAME_MAX] = { 0, };;
719         dp = opendir(dirname);
720         if (dp != NULL) {
721                 while ((ep = readdir(dp)) != NULL) {
722                         struct stat stFileInfo;
723
724                         snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
725                                  ep->d_name);
726
727                         if (stat(abs_filename, &stFileInfo) < 0)
728                                 perror(abs_filename);
729                         else {
730                                 /* If file is rpm then get the size from rpm header. */
731                                 if(strstr(ep->d_name,".rpm")){
732                                         size = _ri_calculate_rpm_size(abs_filename);
733                                         if( size == 0){
734                                                 _LOGE("\n error in computing the rpm's size");
735                                         }
736                                         total += size;
737                                 }else{
738                                 total += (unsigned long)stFileInfo.st_size;
739                                 }
740
741                                 if (S_ISDIR(stFileInfo.st_mode)) {
742                                         if (strcmp(ep->d_name, ".")
743                                             && strcmp(ep->d_name, "..")) {
744                                                 _ri_calculate_dir_size
745                                                     (abs_filename);
746                                         }
747                                 } else {
748                                         /*Do Nothing */
749                                 }
750                         }
751                 }
752                 (void)closedir(dp);
753         } else {
754                 _LOGE("\n error in opening directory ");
755         }
756         return (total/SIZE_KB);
757 }
758
759
760 /*
761 This function unzip the wgt package.
762 It read and validate the config.xml file.
763 It checks whether the free size avaiable to install this package.
764 */
765
766 int _ri_wgt_package_extract(char *pkgid)
767 {
768         if(pkgid == NULL)
769                 return RPM_INSTALLER_ERR_INTERNAL;
770
771         int ret = RPM_INSTALLER_SUCCESS;
772         const char *argv[5] = { RPM_UNZIP, pkgid, "-d", DIR_RPM_INSTALLER_APPLICATIONS_TEMP, NULL};
773         char config_file_name[PATH_MAX] = {0};
774         pkginfo *info = NULL;
775         unsigned long free_mem = 0;
776         unsigned long reqd_size = 0;
777         mode_t mode = DIR_PERMS;
778
779         /* 1. Delete the temp folder if already present*/
780         if (!access(DIR_RPM_INSTALLER_APPLICATIONS_TEMP, F_OK)) {
781                 _ri_recursive_delete_dir(DIR_RPM_INSTALLER_APPLICATIONS_TEMP);
782                 (void)remove(DIR_RPM_INSTALLER_APPLICATIONS_TEMP);
783         }
784
785         /* 1.2 Create temp folder */
786         ret = mkdir(DIR_RPM_INSTALLER_APPLICATIONS_TEMP, mode);
787         if (ret != 0) {
788                 _LOGE("Temporary folder creation failed");
789                 return RPM_INSTALLER_ERR_INTERNAL;
790         }
791         /* 1.3 Unzip wgt to temp folder*/
792         ret = _ri_xsystem(argv);
793         if (ret != 0) {
794                 _LOGE("Unzip to Temporary folder failed");
795                 return  RPM_INSTALLER_ERR_INTERNAL;
796         }
797
798         /* Read the config.xml file and get the information*/
799         snprintf(config_file_name,PATH_MAX,"%s/%s", DIR_RPM_INSTALLER_APPLICATIONS_TEMP,WGT_CONFIG);
800         _LOGD("Config File is [%s]",config_file_name);
801         if(access(config_file_name,F_OK)){
802                 /* Return if info config is absent */
803                 _LOGE("No Config File [%s] found\n", config_file_name);
804                 return  RPM_INSTALLER_ERR_NO_CONFIG;
805         }
806         _LOGD("Config File [%s] found\n", config_file_name);
807
808         /*populate pkginfo */
809         info = (pkginfo *)calloc(1, sizeof(pkginfo));
810         if (info == NULL) {
811                 _LOGE("Memory allocation failed");
812                 return  RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY;
813         }
814
815         /* Parse config file and store the info in pkginfo struct */
816         ret = _ri_stream_config_file(config_file_name,info);
817         if(ret != RPM_INSTALLER_SUCCESS){
818                 _LOGE("Config file's parsing Failed");
819                 if(info){
820                         free(info);
821                         info = NULL;
822                 }
823                 return RPM_INSTALLER_ERR_INTERNAL;
824         }
825
826         /* 3. Validate the pkginfo*/
827         if (strlen(info->package_name) == 0 || strlen(info->version) == 0) {
828                 _LOGE("Package name or version is not found in Config File");
829                 if (info) {
830                         free(info);
831                         info = NULL;
832                 }
833                 return RPM_INSTALLER_ERR_INVALID_CONFIG;
834         }
835
836         /* 4. Check the free memory  in RW partition*/
837         ret = _ri_get_available_free_memory(RPM_INSTALLER_RW_INSTALL_PATH, &free_mem);
838         if (ret<0) {
839                 _LOGE("Error in getting available free memory");
840                 if (info) {
841                         free(info);
842                         info = NULL;
843                 }
844                 return RPM_INSTALLER_ERR_INTERNAL;
845         } else {
846                 /* Compare with size required by package*/
847                 reqd_size = _ri_calculate_dir_size(DIR_RPM_INSTALLER_APPLICATIONS_TEMP);
848                 if (reqd_size ==0) {
849                         _LOGE("Error in getting file size");
850                         if (info) {
851                                 free(info);
852                                 info = NULL;
853                         }
854                         return RPM_INSTALLER_ERR_INTERNAL;
855                 } else {
856                         if (reqd_size > free_mem) {
857                                 _LOGE("Not enough memory");
858                                 if (info) {
859                                         free(info);
860                                         info = NULL;
861                                 }
862                                 return  RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY;
863                         }
864                 }
865         }
866
867         _LOGD("Required size to install pkg is [%lu KB] and available memory is  [%lu KB]",reqd_size,free_mem);
868
869         if (info) {
870                 free(info);
871                 info = NULL;
872         }
873
874         return ret;
875 }
876
877 int _verify_wgt_package_signature_files(void)
878 {
879
880         char buff[PATH_MAX] = {0};
881         int ret = RPM_INSTALLER_SUCCESS;
882         char cwd[PATH_MAX]={0};
883         char *temp = NULL;
884         int visibility = 0;
885
886         temp = getcwd(cwd, PATH_MAX);
887         if ( ( temp == NULL) || (cwd[0] == '\0')) {
888                 _LOGE("@getcwd() failed.\n");
889                 ret = RPM_INSTALLER_ERR_INTERNAL;
890                 goto end;
891         }
892
893         ret = chdir(DIR_RPM_INSTALLER_APPLICATIONS_TEMP);
894         if(ret != 0){
895                 _LOGE("Change directory failed!");
896                 goto end;
897         }
898
899         /*Verify the author-signature file */
900         memset(buff, '\0', PATH_MAX);
901         snprintf(buff, PATH_MAX, "%s/%s",DIR_RPM_INSTALLER_APPLICATIONS_TEMP,AUTHOR_SIGNATURE_XML);
902
903         if (access(buff, F_OK) == 0) {
904                 _LOGD("auth-signature.xml found in %s\n", DIR_RPM_INSTALLER_APPLICATIONS_TEMP);
905                 ret = _ri_verify_sig_and_cert(buff, &visibility);
906                 if (ret) {
907                         _LOGE("Failed to verify [%s]\n", buff);
908                         ret = RPM_INSTALLER_ERR_SIG_INVALID;
909                         goto end;
910                 }else{
911                 _LOGD("Successfully verified [%s]\n", buff);
912                 }
913         }
914
915         /*Verify the signature2.xml file */
916         memset(buff, '\0', PATH_MAX);
917         snprintf(buff, PATH_MAX, "%s/%s",DIR_RPM_INSTALLER_APPLICATIONS_TEMP,SIGNATURE2_XML);
918
919         if (access(buff, F_OK) == 0) {
920                 _LOGD("signature2.xml found in %s\n", DIR_RPM_INSTALLER_APPLICATIONS_TEMP);
921                 ret = _ri_verify_sig_and_cert(buff, &visibility);
922                 if (ret) {
923                         _LOGE("Failed to verify [%s]\n", buff);
924                         ret = RPM_INSTALLER_ERR_SIG_INVALID;
925                         goto end;
926                 }else{
927                 _LOGD("Successfully verified [%s]\n", buff);
928                 }
929         }
930
931         /*Verify the signature1.xml file*/
932         memset(buff, '\0', PATH_MAX);
933         snprintf(buff,PATH_MAX,"%s/%s", DIR_RPM_INSTALLER_APPLICATIONS_TEMP,SIGNATURE1_XML);
934
935         if (access(buff, F_OK) == 0) {
936                 _LOGD("signature1.xml found in %s\n", DIR_RPM_INSTALLER_APPLICATIONS_TEMP);
937                 ret = _ri_verify_sig_and_cert(buff, &visibility);
938                 if (ret) {
939                         _LOGE("Failed to verify [%s]\n", buff);
940                         ret = RPM_INSTALLER_ERR_SIG_INVALID;
941                         goto end;
942                 }else{
943                 _LOGD("Successfully verified [%s]\n", buff);
944                 }
945         }
946
947         if(chdir(cwd)){
948                 _LOGE("chdir failed [%s]",strerror(errno));
949                 ret = RPM_INSTALLER_ERR_INTERNAL;
950         }
951
952         end:
953
954                 return ret;
955
956 }
957
958 char* _get_rpm_file_from_wgt_package(char* dirname)
959 {
960
961         DIR *dp = NULL;
962         struct dirent *ep = NULL;
963         char abs_filename[FILENAME_MAX] = { 0, };
964         dp = opendir(dirname);
965         int found = 0;
966         if (dp != NULL) {
967                 while ((ep = readdir(dp)) != NULL) {
968                         snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
969                                  ep->d_name);
970                         if (strstr(abs_filename,".rpm")!=NULL){
971                                 found = 1;
972                                 break;
973                         }
974                 }
975                 (void)closedir(dp);
976         }
977
978         if(found){
979                 _LOGD("rpm name is [%s]",abs_filename);
980                 return strdup(abs_filename);
981         }
982
983         return NULL;
984
985 }
986
987 /*
988 This function processes the modified wgt package .
989 */
990 int _ri_process_wgt_package(char** pkgid)
991 {
992         if(*pkgid == NULL)
993                 return RPM_INSTALLER_ERR_INTERNAL;
994
995         unsigned long free_mem = 0;
996         unsigned long file_size = 0;
997         int ret = RPM_INSTALLER_SUCCESS;
998
999
1000         /* check memory available*/
1001         ret = _ri_get_available_free_memory(RPM_INSTALLER_RW_INSTALL_PATH, &free_mem);
1002         if (ret<0) {
1003                 _LOGE("Error in getting available free memory");
1004                 return RPM_INSTALLER_ERR_INTERNAL;
1005         } else {
1006                 file_size = _ri_calculate_file_size(*pkgid);
1007                 if (file_size <=0) {
1008                         _LOGE("Error in getting file size");
1009                         return RPM_INSTALLER_ERR_INTERNAL;
1010                 } else {
1011                         if (file_size > free_mem) {
1012                                 _LOGE("Not enough memory");
1013                                 return RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY;
1014                         }
1015                 }
1016         }
1017
1018         _LOGD("Package file [%s] size is [%lu]KB and free size in RW directory is [%lu]KB",*pkgid,file_size,free_mem);
1019
1020         /* unzip the wgt package */
1021         ret = _ri_wgt_package_extract(*pkgid);
1022         if(ret != RPM_INSTALLER_SUCCESS)
1023                 return ret;
1024
1025         _LOGD("wgt package is extracted to [%s]",DIR_RPM_INSTALLER_APPLICATIONS_TEMP);
1026
1027         ret = _verify_wgt_package_signature_files();
1028         if(ret != RPM_INSTALLER_SUCCESS){
1029                 _LOGE("signature verification [%d]",ret);
1030                 return ret;
1031         }
1032         _LOGD("Verification of wgt package's signature files is done");
1033
1034         if(*pkgid){
1035                 free(*pkgid);
1036                 *pkgid = NULL;
1037         }
1038         /* Change the data->pkgid to the unzipped package's rpm */
1039         *pkgid = _get_rpm_file_from_wgt_package(DIR_RPM_INSTALLER_APPLICATIONS_TEMP);
1040         if(*pkgid == NULL)
1041                 return RPM_INSTALLER_ERR_INTERNAL;
1042         else
1043                 _LOGD("rpm is [%s]",*pkgid);
1044
1045         return RPM_INSTALLER_SUCCESS;
1046 }