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