Update source from tizen 2.3
[platform/core/base/rpm-installer.git] / backend-lib / src / librpminternals.c
1 /*
2  * rpm-installer
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7  * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <stdarg.h>
27 #include <unistd.h>
28 #include <sys/wait.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <regex.h>
32 #include <dlog.h>
33 /*rpm specific headers*/
34 #include <rpmlib.h>
35 #include <header.h>
36 #include <rpmts.h>
37 #include <rpmdb.h>
38 #include <rpmlog.h>
39
40 #include "librpminternals.h"
41 #include "rpm-installer-util.h"
42
43 int _librpm_app_is_installed(const char *pkgid)
44 {
45         rpmts ts = NULL;
46         int ret = 0;
47         int found = 0;
48         rpmdbMatchIterator mi;
49
50         ts = rpmtsCreate();
51         mi = rpmtsInitIterator(ts, RPMTAG_NAME, pkgid, 0);
52         while (NULL != rpmdbNextIterator(mi)) {
53                 found = 1;
54         }
55
56         if (found == 0) {
57                 _LOGD("Package not found in DB\n");
58                 ret = 0;
59                 goto err;
60         }
61         else {
62                  _LOGD("Package found in DB\n");
63                 ret = 1;
64                 goto err;
65         }
66 err:
67         rpmtsFree(ts);
68         rpmdbFreeIterator(mi);
69         return ret;
70 }
71
72 int _librpm_get_installed_package_info(const char *pkgid,
73                         package_manager_pkg_detail_info_t *pkg_detail_info)
74 {
75         rpmts ts = NULL;
76         Header hdr = NULL;
77         int found = 0;
78         int ret = 0;
79         rpmdbMatchIterator mi;
80         rpmtd td, tn, tv, ta;
81
82         td = rpmtdNew();
83         tn = rpmtdNew();
84         tv = rpmtdNew();
85         ta = rpmtdNew();
86         ts = rpmtsCreate();
87
88         mi = rpmtsInitIterator(ts, RPMTAG_NAME, pkgid, 0);
89         while (NULL != (hdr = rpmdbNextIterator(mi))) {
90                 hdr = headerLink(hdr);
91                 found = 1;
92                 break;
93         }
94
95         /*Print the header info */
96         if (found == 0) {
97                 _LOGE("Package not found in DB\n");
98                 ret = LIBRPM_ERROR;
99                 goto err;
100         }
101         /*Name*/
102         headerGet(hdr, RPMTAG_NAME, tn, HEADERGET_MINMEM);
103         strncpy(pkg_detail_info->pkgid, rpmtdGetString(tn), PKG_NAME_STRING_LEN_MAX-1);
104         /*Version*/
105         headerGet(hdr, RPMTAG_VERSION, tv, HEADERGET_MINMEM);
106         strncpy(pkg_detail_info->version, rpmtdGetString(tv), PKG_VERSION_STRING_LEN_MAX-1);
107         /*Description*/
108         headerGet(hdr, RPMTAG_DESCRIPTION, td, HEADERGET_MINMEM);
109         strncpy(pkg_detail_info->pkg_description, rpmtdGetString(td), PKG_VALUE_STRING_LEN_MAX-1);
110         /*Size*/
111         headerGet(hdr, RPMTAG_SIZE, ta, HEADERGET_MINMEM);
112         pkg_detail_info->app_size = rpmtdGetNumber(ta);
113         ret = LIBRPM_SUCCESS;
114
115 err:
116         headerFree(hdr);
117         rpmtdFreeData(tn);
118         rpmtdFree(tn);
119         rpmtdFreeData(td);
120         rpmtdFree(td);
121         rpmtdFreeData(ta);
122         rpmtdFree(ta);
123         rpmtdFreeData(tv);
124         rpmtdFree(tv);
125         rpmdbFreeIterator(mi);
126         rpmtsFree(ts);
127
128         return ret;
129
130 }
131
132 int _librpm_get_package_header_info(const char *pkg_path,
133                                 package_manager_pkg_detail_info_t *pkg_detail_info)
134 {
135         int ret = 0;
136         rpmts ts = NULL;
137         rpmtd td = NULL;
138         FD_t fd;
139         rpmRC rc;
140         Header hdr = NULL;
141         rpmVSFlags vsflags = 0;
142
143         fd = Fopen(pkg_path, "r.ufdio");
144         if ((!fd) || Ferror(fd)) {
145                 _LOGE("Failed to open package file (%s)\n", Fstrerror(fd));
146                 ret = LIBRPM_ERROR;
147                 goto err;
148         }
149
150         ts = rpmtsCreate();
151         td = rpmtdNew();
152         hdr = headerNew();
153
154         vsflags |= _RPMVSF_NODIGESTS;
155         vsflags |= _RPMVSF_NOSIGNATURES;
156         vsflags |= RPMVSF_NOHDRCHK;
157         (void) rpmtsSetVSFlags(ts, vsflags);
158
159         rc = rpmReadPackageFile(ts, fd, pkg_path, &hdr);
160         if (rc != RPMRC_OK) {
161                 _LOGE("Could not read package file\n");
162                 ret = LIBRPM_ERROR;
163                 goto err;
164         }
165         Fclose(fd);
166         /*Name*/
167         headerGet(hdr, RPMTAG_NAME, td, HEADERGET_MINMEM);
168         strncpy(pkg_detail_info->pkgid, rpmtdGetString(td), PKG_NAME_STRING_LEN_MAX-1);
169         rpmtdReset(td);
170         /*Version*/
171         headerGet(hdr, RPMTAG_VERSION, td, HEADERGET_MINMEM);
172         strncpy(pkg_detail_info->version, rpmtdGetString(td), PKG_VERSION_STRING_LEN_MAX-1);
173         rpmtdReset(td);
174         /*Description*/
175         headerGet(hdr, RPMTAG_DESCRIPTION, td, HEADERGET_MINMEM);
176         strncpy(pkg_detail_info->pkg_description, rpmtdGetString(td), PKG_VALUE_STRING_LEN_MAX-1);
177         rpmtdReset(td);
178         /*Size*/
179         headerGet(hdr, RPMTAG_SIZE, td, HEADERGET_MINMEM);
180         pkg_detail_info->app_size = rpmtdGetNumber(td);
181
182         ret = LIBRPM_SUCCESS;
183 err:
184         rpmtdFreeData(td);
185         rpmtdFree(td);
186         headerFree(hdr);
187         rpmtsFree(ts);
188         return ret;
189
190 }
191
192 long long _librpm_calculate_dir_size(const char *dirname)
193 {
194         long long total = 0;
195         long long ret = 0;
196         int q = 0; /*quotient*/
197         int r = 0; /*remainder*/
198         DIR *dp = NULL;
199         struct dirent *ep = NULL;
200         struct stat fileinfo;
201         char abs_filename[FILENAME_MAX] = { 0, };
202         if (dirname == NULL) {
203                 _LOGE(
204                                 "dirname is NULL");
205                 return LIBRPM_ERROR;
206         }
207         dp = opendir(dirname);
208         if (dp != NULL) {
209                 while ((ep = readdir(dp)) != NULL) {
210                         if (!strcmp(ep->d_name, ".") ||
211                                 !strcmp(ep->d_name, "..")) {
212                                 continue;
213                         }
214                         snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
215                                  ep->d_name);
216                         if (stat(abs_filename, &fileinfo) < 0)
217                                 perror(abs_filename);
218                         else {
219                                 if (S_ISDIR(fileinfo.st_mode)) {
220                                         total += fileinfo.st_size;
221                                         if (strcmp(ep->d_name, ".")
222                                             && strcmp(ep->d_name, "..")) {
223                                                 ret = _librpm_calculate_dir_size
224                                                     (abs_filename);
225                                                 total = total + ret;
226                                         }
227                                 } else {
228                                         /*It is a file. Calculate the actual
229                                         size occupied (in terms of 4096 blocks)*/
230                                 q = (fileinfo.st_size / BLOCK_SIZE);
231                                 r = (fileinfo.st_size % BLOCK_SIZE);
232                                 if (r) {
233                                         q = q + 1;
234                                 }
235                                 total += q * BLOCK_SIZE;
236                                 }
237                         }
238                 }
239                 (void)closedir(dp);
240         } else {
241                 _LOGE(
242                              "Couldn't open the directory\n");
243                 return -1;
244         }
245         return total;
246
247 }