]>
Commit | Line | Data |
---|---|---|
e2faeb46 AF |
1 | /* |
2 | * be_files.c | |
23229097 | 3 | * |
d37ad048 AG |
4 | * Copyright (c) 2006 by Christian Hamar <krics@linuxforum.hu> |
5 | * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> | |
23229097 | 6 | * |
e2faeb46 AF |
7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
9781d0d6 | 18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
e2faeb46 AF |
19 | */ |
20 | ||
21 | #include "config.h" | |
869e81e1 | 22 | |
e2faeb46 AF |
23 | #include <unistd.h> |
24 | #include <stdio.h> | |
25 | #include <stdlib.h> | |
26 | #include <errno.h> | |
27 | #include <string.h> | |
7965345d | 28 | #include <stdint.h> /* intmax_t */ |
e2faeb46 AF |
29 | #include <sys/stat.h> |
30 | #include <dirent.h> | |
47622eef AG |
31 | #include <ctype.h> |
32 | #include <time.h> | |
e2faeb46 | 33 | #include <limits.h> /* PATH_MAX */ |
aa942a12 | 34 | #include <locale.h> /* setlocale */ |
869e81e1 | 35 | |
2f4ee434 XC |
36 | /* libarchive */ |
37 | #include <archive.h> | |
38 | #include <archive_entry.h> | |
39 | ||
869e81e1 DM |
40 | /* libalpm */ |
41 | #include "db.h" | |
42 | #include "alpm_list.h" | |
04600384 | 43 | #include "cache.h" |
e2faeb46 AF |
44 | #include "log.h" |
45 | #include "util.h" | |
e2faeb46 | 46 | #include "alpm.h" |
d37ad048 | 47 | #include "handle.h" |
aa1c0ba9 | 48 | #include "package.h" |
0c2cc108 | 49 | #include "delta.h" |
c244cfec | 50 | #include "deps.h" |
04600384 | 51 | #include "dload.h" |
d37ad048 | 52 | |
e8275fa9 | 53 | |
34e1413d XC |
54 | static int checkdbdir(pmdb_t *db) |
55 | { | |
56 | struct stat buf; | |
72883e3b | 57 | const char *path = _alpm_db_path(db); |
34e1413d XC |
58 | |
59 | if(stat(path, &buf) != 0) { | |
60 | _alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n", | |
61 | path); | |
62 | if(_alpm_makepath(path) != 0) { | |
63 | RET_ERR(PM_ERR_SYSTEM, -1); | |
64 | } | |
65 | } else if(!S_ISDIR(buf.st_mode)) { | |
1df3b919 | 66 | _alpm_log(PM_LOG_WARNING, _("removing invalid database: %s\n"), path); |
34e1413d XC |
67 | if(unlink(path) != 0 || _alpm_makepath(path) != 0) { |
68 | RET_ERR(PM_ERR_SYSTEM, -1); | |
69 | } | |
70 | } | |
71 | return(0); | |
72 | } | |
73 | ||
2f4ee434 XC |
74 | /* create list of directories in db */ |
75 | static int dirlist_from_tar(const char *archive, alpm_list_t **dirlist) | |
76 | { | |
77 | struct archive *_archive; | |
78 | struct archive_entry *entry; | |
79 | ||
80 | if((_archive = archive_read_new()) == NULL) | |
81 | RET_ERR(PM_ERR_LIBARCHIVE, -1); | |
82 | ||
83 | archive_read_support_compression_all(_archive); | |
84 | archive_read_support_format_all(_archive); | |
85 | ||
86 | if(archive_read_open_filename(_archive, archive, | |
87 | ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { | |
88 | _alpm_log(PM_LOG_ERROR, _("could not open %s: %s\n"), archive, | |
89 | archive_error_string(_archive)); | |
90 | RET_ERR(PM_ERR_PKG_OPEN, -1); | |
91 | } | |
92 | ||
93 | while(archive_read_next_header(_archive, &entry) == ARCHIVE_OK) { | |
94 | const struct stat *st; | |
95 | const char *entryname; /* the name of the file in the archive */ | |
96 | ||
97 | st = archive_entry_stat(entry); | |
98 | entryname = archive_entry_pathname(entry); | |
99 | ||
100 | if(S_ISDIR(st->st_mode)) { | |
101 | char *name = strdup(entryname); | |
102 | *dirlist = alpm_list_add(*dirlist, name); | |
103 | } | |
104 | } | |
105 | archive_read_finish(_archive); | |
106 | ||
107 | *dirlist = alpm_list_msort(*dirlist, alpm_list_count(*dirlist), _alpm_str_cmp); | |
108 | return(0); | |
109 | } | |
110 | ||
dff73a2a DM |
111 | static int is_dir(const char *path, struct dirent *entry) |
112 | { | |
113 | #ifdef DT_DIR | |
114 | return(entry->d_type == DT_DIR); | |
115 | #else | |
116 | char buffer[PATH_MAX]; | |
117 | snprintf(buffer, PATH_MAX, "%s/%s", path, entry->d_name); | |
118 | ||
119 | struct stat sbuf; | |
120 | if (!stat(buffer, &sbuf)) { | |
121 | return(S_ISDIR(sbuf.st_mode)); | |
122 | } | |
123 | ||
124 | return(0); | |
125 | #endif | |
126 | } | |
127 | ||
2f4ee434 XC |
128 | /* create list of directories in db */ |
129 | static int dirlist_from_fs(const char *syncdbpath, alpm_list_t **dirlist) | |
130 | { | |
131 | DIR *dbdir; | |
132 | struct dirent *ent = NULL; | |
2f4ee434 XC |
133 | |
134 | dbdir = opendir(syncdbpath); | |
135 | if (dbdir != NULL) { | |
136 | while((ent = readdir(dbdir)) != NULL) { | |
137 | char *name = ent->d_name; | |
138 | size_t len; | |
139 | char *entry; | |
140 | ||
141 | if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { | |
142 | continue; | |
143 | } | |
144 | ||
dff73a2a | 145 | if(!is_dir(syncdbpath, ent)) { |
2f4ee434 XC |
146 | continue; |
147 | } | |
148 | ||
149 | len = strlen(name); | |
150 | MALLOC(entry, len + 2, RET_ERR(PM_ERR_MEMORY, -1)); | |
151 | strcpy(entry, name); | |
152 | entry[len] = '/'; | |
153 | entry[len+1] = '\0'; | |
154 | *dirlist = alpm_list_add(*dirlist, entry); | |
155 | } | |
1aa1d002 | 156 | closedir(dbdir); |
2f4ee434 | 157 | } |
2f4ee434 XC |
158 | |
159 | *dirlist = alpm_list_msort(*dirlist, alpm_list_count(*dirlist), _alpm_str_cmp); | |
160 | return(0); | |
161 | } | |
162 | ||
163 | /* remove old directories from dbdir */ | |
164 | static int remove_olddir(const char *syncdbpath, alpm_list_t *dirlist) | |
165 | { | |
166 | alpm_list_t *i; | |
167 | for (i = dirlist; i; i = i->next) { | |
168 | const char *name = i->data; | |
169 | char *dbdir; | |
170 | size_t len = strlen(syncdbpath) + strlen(name) + 2; | |
171 | MALLOC(dbdir, len, RET_ERR(PM_ERR_MEMORY, -1)); | |
172 | snprintf(dbdir, len, "%s%s", syncdbpath, name); | |
173 | _alpm_log(PM_LOG_DEBUG, "removing: %s\n", dbdir); | |
174 | if(_alpm_rmrf(dbdir) != 0) { | |
175 | _alpm_log(PM_LOG_ERROR, _("could not remove database directory %s\n"), dbdir); | |
176 | free(dbdir); | |
177 | RET_ERR(PM_ERR_DB_REMOVE, -1); | |
178 | } | |
179 | free(dbdir); | |
180 | } | |
181 | return(0); | |
182 | } | |
183 | ||
04600384 | 184 | /** Update a package database |
63fc9360 SN |
185 | * |
186 | * An update of the package database \a db will be attempted. Unless | |
187 | * \a force is true, the update will only be performed if the remote | |
188 | * database was modified since the last update. | |
189 | * | |
190 | * A transaction is necessary for this operation, in order to obtain a | |
191 | * database lock. During this transaction the front-end will be informed | |
192 | * of the download progress of the database via the download callback. | |
193 | * | |
194 | * Example: | |
195 | * @code | |
196 | * pmdb_t *db; | |
197 | * int result; | |
198 | * db = alpm_list_getdata(alpm_option_get_syncdbs()); | |
8ff3b870 | 199 | * if(alpm_trans_init(0, NULL, NULL, NULL) == 0) { |
63fc9360 SN |
200 | * result = alpm_db_update(0, db); |
201 | * alpm_trans_release(); | |
202 | * | |
203 | * if(result > 0) { | |
204 | * printf("Unable to update database: %s\n", alpm_strerrorlast()); | |
205 | * } else if(result < 0) { | |
206 | * printf("Database already up to date\n"); | |
207 | * } else { | |
208 | * printf("Database updated\n"); | |
209 | * } | |
210 | * } | |
211 | * @endcode | |
212 | * | |
213 | * @ingroup alpm_databases | |
214 | * @note After a successful update, the \link alpm_db_get_pkgcache() | |
215 | * package cache \endlink will be invalidated | |
04600384 DM |
216 | * @param force if true, then forces the update, otherwise update only in case |
217 | * the database isn't up to date | |
218 | * @param db pointer to the package database to update | |
219 | * @return 0 on success, > 0 on error (pm_errno is set accordingly), < 0 if up | |
220 | * to date | |
e8275fa9 | 221 | */ |
04600384 | 222 | int SYMEXPORT alpm_db_update(int force, pmdb_t *db) |
e8275fa9 | 223 | { |
a8355994 | 224 | char *dbfile, *dbfilepath, *syncpath; |
be2f4319 | 225 | const char *dbpath, *syncdbpath; |
f6c7de77 DM |
226 | alpm_list_t *newdirlist = NULL, *olddirlist = NULL; |
227 | alpm_list_t *onlynew = NULL, *onlyold = NULL; | |
0966c33a | 228 | size_t len; |
04600384 DM |
229 | int ret; |
230 | ||
da648bc2 AG |
231 | ALPM_LOG_FUNC; |
232 | ||
04600384 DM |
233 | /* Sanity checks */ |
234 | ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); | |
235 | ASSERT(db != NULL && db != handle->db_local, RET_ERR(PM_ERR_WRONG_ARGS, -1)); | |
236 | /* Verify we are in a transaction. This is done _mainly_ because we need a DB | |
237 | * lock - if we update without a db lock, we may kludge some other pacman | |
238 | * process that _has_ a lock. | |
239 | */ | |
240 | ASSERT(handle->trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); | |
241 | ASSERT(handle->trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1)); | |
04600384 DM |
242 | |
243 | if(!alpm_list_find_ptr(handle->dbs_sync, db)) { | |
244 | RET_ERR(PM_ERR_DB_NOT_FOUND, -1); | |
245 | } | |
246 | ||
68dcabdf | 247 | len = strlen(db->treename) + 4; |
0966c33a | 248 | MALLOC(dbfile, len, RET_ERR(PM_ERR_MEMORY, -1)); |
68dcabdf | 249 | sprintf(dbfile, "%s.db", db->treename); |
0966c33a | 250 | |
04600384 | 251 | dbpath = alpm_option_get_dbpath(); |
a8355994 AM |
252 | len = strlen(dbpath) + 6; |
253 | MALLOC(syncpath, len, RET_ERR(PM_ERR_MEMORY, -1)); | |
254 | sprintf(syncpath, "%s%s", dbpath, "sync/"); | |
04600384 | 255 | |
a8355994 | 256 | ret = _alpm_download_single_file(dbfile, db->servers, syncpath, force); |
0966c33a | 257 | free(dbfile); |
a8355994 | 258 | free(syncpath); |
04600384 DM |
259 | |
260 | if(ret == 1) { | |
d2dbb04a | 261 | /* files match, do nothing */ |
04600384 DM |
262 | pm_errno = 0; |
263 | return(1); | |
264 | } else if(ret == -1) { | |
265 | /* pm_errno was set by the download code */ | |
266 | _alpm_log(PM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerrorlast()); | |
267 | return(-1); | |
2f4ee434 XC |
268 | } |
269 | ||
be2f4319 | 270 | syncdbpath = _alpm_db_path(db); |
2f4ee434 XC |
271 | |
272 | /* form the path to the db location */ | |
a8355994 | 273 | len = strlen(dbpath) + strlen(db->treename) + 9; |
2f4ee434 | 274 | MALLOC(dbfilepath, len, RET_ERR(PM_ERR_MEMORY, -1)); |
a8355994 | 275 | sprintf(dbfilepath, "%ssync/%s.db", dbpath, db->treename); |
2f4ee434 XC |
276 | |
277 | if(force) { | |
278 | /* if forcing update, remove the old dir and extract the db */ | |
72883e3b | 279 | if(_alpm_rmrf(syncdbpath) != 0) { |
34e1413d XC |
280 | _alpm_log(PM_LOG_ERROR, _("could not remove database %s\n"), db->treename); |
281 | RET_ERR(PM_ERR_DB_REMOVE, -1); | |
d2dbb04a DM |
282 | } else { |
283 | _alpm_log(PM_LOG_DEBUG, "database dir %s removed\n", _alpm_db_path(db)); | |
04600384 | 284 | } |
be2f4319 DM |
285 | } else { |
286 | /* if not forcing, only remove and extract what is necessary */ | |
be2f4319 | 287 | ret = dirlist_from_tar(dbfilepath, &newdirlist); |
0966c33a | 288 | if(ret) { |
be2f4319 DM |
289 | goto cleanup; |
290 | } | |
291 | ret = dirlist_from_fs(syncdbpath, &olddirlist); | |
292 | if(ret) { | |
be2f4319 | 293 | goto cleanup; |
04600384 | 294 | } |
2f4ee434 | 295 | |
f6c7de77 | 296 | alpm_list_diff_sorted(olddirlist, newdirlist, _alpm_str_cmp, &onlyold, &onlynew); |
2f4ee434 | 297 | |
be2f4319 | 298 | ret = remove_olddir(syncdbpath, onlyold); |
be2f4319 DM |
299 | if(ret) { |
300 | goto cleanup; | |
301 | } | |
2f4ee434 XC |
302 | } |
303 | ||
2f4ee434 XC |
304 | /* Cache needs to be rebuilt */ |
305 | _alpm_db_free_pkgcache(db); | |
306 | ||
2f4ee434 | 307 | checkdbdir(db); |
f6c7de77 | 308 | ret = _alpm_unpack(dbfilepath, syncdbpath, onlynew, 0); |
2f4ee434 XC |
309 | |
310 | cleanup: | |
f6c7de77 DM |
311 | FREELIST(newdirlist); |
312 | FREELIST(olddirlist); | |
313 | alpm_list_free(onlynew); | |
314 | alpm_list_free(onlyold); | |
315 | ||
2f4ee434 | 316 | free(dbfilepath); |
2f4ee434 XC |
317 | |
318 | if(ret) { | |
319 | RET_ERR(PM_ERR_SYSTEM, -1); | |
e8275fa9 AG |
320 | } |
321 | ||
04600384 | 322 | return(0); |
e8275fa9 AG |
323 | } |
324 | ||
e2faeb46 | 325 | |
ccc1c731 | 326 | static int splitname(const char *target, pmpkg_t *pkg) |
f7bbfe40 DM |
327 | { |
328 | /* the format of a db entry is as follows: | |
329 | * package-version-rel/ | |
330 | * package name can contain hyphens, so parse from the back- go back | |
331 | * two hyphens and we have split the version from the name. | |
332 | */ | |
333 | char *tmp, *p, *q; | |
334 | ||
ccc1c731 | 335 | if(target == NULL || pkg == NULL) { |
f7bbfe40 DM |
336 | return(-1); |
337 | } | |
ccc1c731 | 338 | STRDUP(tmp, target, RET_ERR(PM_ERR_MEMORY, -1)); |
f7bbfe40 DM |
339 | p = tmp + strlen(tmp); |
340 | ||
341 | /* do the magic parsing- find the beginning of the version string | |
342 | * by doing two iterations of same loop to lop off two hyphens */ | |
343 | for(q = --p; *q && *q != '-'; q--); | |
344 | for(p = --q; *p && *p != '-'; p--); | |
345 | if(*p != '-' || p == tmp) { | |
346 | return(-1); | |
347 | } | |
348 | ||
349 | /* copy into fields and return */ | |
ccc1c731 DM |
350 | if(pkg->version) { |
351 | FREE(pkg->version); | |
f7bbfe40 | 352 | } |
ccc1c731 | 353 | STRDUP(pkg->version, p+1, RET_ERR(PM_ERR_MEMORY, -1)); |
f7bbfe40 DM |
354 | /* insert a terminator at the end of the name (on hyphen)- then copy it */ |
355 | *p = '\0'; | |
ccc1c731 DM |
356 | if(pkg->name) { |
357 | FREE(pkg->name); | |
f7bbfe40 | 358 | } |
ccc1c731 | 359 | STRDUP(pkg->name, tmp, RET_ERR(PM_ERR_MEMORY, -1)); |
f7bbfe40 DM |
360 | |
361 | free(tmp); | |
362 | return(0); | |
363 | } | |
364 | ||
f6711472 | 365 | int _alpm_db_populate(pmdb_t *db) |
e2faeb46 | 366 | { |
f6711472 | 367 | int count = 0; |
e2faeb46 | 368 | struct dirent *ent = NULL; |
72883e3b | 369 | const char *dbpath; |
14230869 | 370 | DIR *dbdir; |
e2faeb46 | 371 | |
da648bc2 AG |
372 | ALPM_LOG_FUNC; |
373 | ||
f6711472 | 374 | ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); |
e2faeb46 | 375 | |
72883e3b DM |
376 | dbpath = _alpm_db_path(db); |
377 | dbdir = opendir(dbpath); | |
14230869 | 378 | if(dbdir == NULL) { |
34e1413d | 379 | return(0); |
14230869 XC |
380 | } |
381 | while((ent = readdir(dbdir)) != NULL) { | |
f6711472 XC |
382 | const char *name = ent->d_name; |
383 | pmpkg_t *pkg; | |
ccc1c731 | 384 | |
f6711472 XC |
385 | if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { |
386 | continue; | |
387 | } | |
dff73a2a | 388 | if(!is_dir(dbpath, ent)) { |
f6711472 | 389 | continue; |
e2faeb46 | 390 | } |
0adceabe | 391 | |
dd98aa85 | 392 | pkg = _alpm_pkg_new(); |
0adceabe | 393 | if(pkg == NULL) { |
14230869 | 394 | closedir(dbdir); |
f6711472 | 395 | return(-1); |
e2faeb46 | 396 | } |
f7bbfe40 | 397 | /* split the db entry name */ |
f6711472 | 398 | if(splitname(name, pkg) != 0) { |
f7bbfe40 | 399 | _alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"), |
f6711472 XC |
400 | name); |
401 | _alpm_pkg_free(pkg); | |
9d9ac66b | 402 | continue; |
0adceabe | 403 | } |
7f5dada8 | 404 | |
444ff956 NG |
405 | /* duplicated database entries are not allowed */ |
406 | if(_alpm_pkg_find(db->pkgcache, pkg->name)) { | |
407 | _alpm_log(PM_LOG_ERROR, _("duplicated database entry '%s'\n"), pkg->name); | |
408 | _alpm_pkg_free(pkg); | |
409 | continue; | |
410 | } | |
411 | ||
7f5dada8 AG |
412 | /* explicitly read with only 'BASE' data, accessors will handle the rest */ |
413 | if(_alpm_db_read(db, pkg, INFRQ_BASE) == -1) { | |
f6711472 | 414 | _alpm_log(PM_LOG_ERROR, _("corrupted database entry '%s'\n"), name); |
a3491224 | 415 | _alpm_pkg_free(pkg); |
f6711472 | 416 | continue; |
e2faeb46 | 417 | } |
d1126db1 DM |
418 | if(db == handle->db_local) { |
419 | pkg->origin = PKG_FROM_LOCALDB; | |
420 | } else { | |
421 | pkg->origin = PKG_FROM_SYNCDB; | |
422 | } | |
f6711472 XC |
423 | pkg->origin_data.db = db; |
424 | /* add to the collection */ | |
425 | _alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n", | |
426 | pkg->name, db->treename); | |
427 | db->pkgcache = alpm_list_add(db->pkgcache, pkg); | |
428 | count++; | |
e2faeb46 AF |
429 | } |
430 | ||
14230869 | 431 | closedir(dbdir); |
f6711472 XC |
432 | db->pkgcache = alpm_list_msort(db->pkgcache, count, _alpm_pkg_cmp); |
433 | return(count); | |
e2faeb46 AF |
434 | } |
435 | ||
0966c33a XC |
436 | /* Note: the return value must be freed by the caller */ |
437 | static char *get_pkgpath(pmdb_t *db, pmpkg_t *info) | |
438 | { | |
439 | size_t len; | |
440 | char *pkgpath; | |
72883e3b | 441 | const char *dbpath; |
0966c33a | 442 | |
72883e3b DM |
443 | dbpath = _alpm_db_path(db); |
444 | len = strlen(dbpath) + strlen(info->name) + strlen(info->version) + 3; | |
0966c33a | 445 | MALLOC(pkgpath, len, RET_ERR(PM_ERR_MEMORY, NULL)); |
72883e3b | 446 | sprintf(pkgpath, "%s%s-%s/", dbpath, info->name, info->version); |
0966c33a XC |
447 | return(pkgpath); |
448 | } | |
449 | ||
a5f630fd | 450 | int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) |
e2faeb46 AF |
451 | { |
452 | FILE *fp = NULL; | |
7fccfc78 | 453 | char path[PATH_MAX]; |
d896527d | 454 | char line[1024]; |
0966c33a | 455 | char *pkgpath = NULL; |
e2faeb46 | 456 | |
da648bc2 AG |
457 | ALPM_LOG_FUNC; |
458 | ||
e8275fa9 AG |
459 | if(db == NULL) { |
460 | RET_ERR(PM_ERR_DB_NULL, -1); | |
461 | } | |
462 | ||
ccc1c731 | 463 | if(info == NULL || info->name == NULL || info->version == NULL) { |
5c9eec55 | 464 | _alpm_log(PM_LOG_DEBUG, "invalid package entry provided to _alpm_db_read, skipping\n"); |
e2faeb46 AF |
465 | return(-1); |
466 | } | |
467 | ||
3bf918dc | 468 | if(info->origin == PKG_FROM_FILE) { |
5c9eec55 | 469 | _alpm_log(PM_LOG_DEBUG, "request to read database info for a file-based package '%s', skipping...\n", info->name); |
3bf918dc AG |
470 | return(-1); |
471 | } | |
472 | ||
ba1806f5 DM |
473 | /* bitmask logic here: |
474 | * infolevel: 00001111 | |
475 | * inforeq: 00010100 | |
476 | * & result: 00000100 | |
477 | * == to inforeq? nope, we need to load more info. */ | |
478 | if((info->infolevel & inforeq) == inforeq) { | |
986409f9 AG |
479 | /* already loaded this info, do nothing */ |
480 | return(0); | |
481 | } | |
4abd710e DM |
482 | _alpm_log(PM_LOG_FUNCTION, "loading package data for %s : level=0x%x\n", |
483 | info->name, inforeq); | |
3bf918dc | 484 | |
aa1c0ba9 | 485 | /* clear out 'line', to be certain - and to make valgrind happy */ |
d896527d | 486 | memset(line, 0, sizeof(line)); |
aa1c0ba9 | 487 | |
0966c33a XC |
488 | pkgpath = get_pkgpath(db, info); |
489 | ||
29bf6814 | 490 | if(access(pkgpath, F_OK)) { |
e2faeb46 | 491 | /* directory doesn't exist or can't be opened */ |
5c9eec55 | 492 | _alpm_log(PM_LOG_DEBUG, "cannot find '%s-%s' in db '%s'\n", |
ea1fef69 | 493 | info->name, info->version, db->treename); |
0966c33a | 494 | goto error; |
e2faeb46 AF |
495 | } |
496 | ||
497 | /* DESC */ | |
498 | if(inforeq & INFRQ_DESC) { | |
0966c33a | 499 | snprintf(path, PATH_MAX, "%sdesc", pkgpath); |
170d6319 | 500 | if((fp = fopen(path, "r")) == NULL) { |
5c9eec55 | 501 | _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); |
e2faeb46 AF |
502 | goto error; |
503 | } | |
504 | while(!feof(fp)) { | |
d896527d | 505 | if(fgets(line, sizeof(line), fp) == NULL) { |
e2faeb46 AF |
506 | break; |
507 | } | |
508 | _alpm_strtrim(line); | |
da1c11cc | 509 | if(strcmp(line, "%NAME%") == 0) { |
d896527d | 510 | if(fgets(line, sizeof(line), fp) == NULL) { |
da1c11cc NG |
511 | goto error; |
512 | } | |
513 | if(strcmp(_alpm_strtrim(line), info->name) != 0) { | |
514 | _alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: name " | |
515 | "mismatch on package %s\n"), db->treename, info->name); | |
516 | } | |
517 | } else if(strcmp(line, "%VERSION%") == 0) { | |
d896527d | 518 | if(fgets(line, sizeof(line), fp) == NULL) { |
da1c11cc NG |
519 | goto error; |
520 | } | |
521 | if(strcmp(_alpm_strtrim(line), info->version) != 0) { | |
522 | _alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: version " | |
523 | "mismatch on package %s\n"), db->treename, info->name); | |
524 | } | |
525 | } else if(strcmp(line, "%FILENAME%") == 0) { | |
d896527d | 526 | if(fgets(line, sizeof(line), fp) == NULL) { |
986409f9 AG |
527 | goto error; |
528 | } | |
ccc1c731 | 529 | STRDUP(info->filename, _alpm_strtrim(line), goto error); |
da1c11cc | 530 | } else if(strcmp(line, "%DESC%") == 0) { |
d896527d | 531 | if(fgets(line, sizeof(line), fp) == NULL) { |
af48c695 AG |
532 | goto error; |
533 | } | |
ccc1c731 DM |
534 | STRDUP(info->desc, _alpm_strtrim(line), goto error); |
535 | } else if(strcmp(line, "%GROUPS%") == 0) { | |
d896527d | 536 | while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { |
ccc1c731 DM |
537 | char *linedup; |
538 | STRDUP(linedup, _alpm_strtrim(line), goto error); | |
539 | info->groups = alpm_list_add(info->groups, linedup); | |
e2faeb46 | 540 | } |
ccc1c731 | 541 | } else if(strcmp(line, "%URL%") == 0) { |
d896527d | 542 | if(fgets(line, sizeof(line), fp) == NULL) { |
e2faeb46 AF |
543 | goto error; |
544 | } | |
ccc1c731 DM |
545 | STRDUP(info->url, _alpm_strtrim(line), goto error); |
546 | } else if(strcmp(line, "%LICENSE%") == 0) { | |
d896527d | 547 | while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { |
ccc1c731 DM |
548 | char *linedup; |
549 | STRDUP(linedup, _alpm_strtrim(line), goto error); | |
550 | info->licenses = alpm_list_add(info->licenses, linedup); | |
e2faeb46 | 551 | } |
ccc1c731 | 552 | } else if(strcmp(line, "%ARCH%") == 0) { |
d896527d | 553 | if(fgets(line, sizeof(line), fp) == NULL) { |
e2faeb46 AF |
554 | goto error; |
555 | } | |
ccc1c731 DM |
556 | STRDUP(info->arch, _alpm_strtrim(line), goto error); |
557 | } else if(strcmp(line, "%BUILDDATE%") == 0) { | |
d896527d | 558 | if(fgets(line, sizeof(line), fp) == NULL) { |
e2faeb46 AF |
559 | goto error; |
560 | } | |
ccc1c731 | 561 | _alpm_strtrim(line); |
47622eef | 562 | |
caea098c | 563 | char first = tolower((unsigned char)line[0]); |
47622eef | 564 | if(first > 'a' && first < 'z') { |
ed848b1c | 565 | struct tm tmp_tm = {0}; /* initialize to null in case of failure */ |
e6673544 | 566 | setlocale(LC_TIME, "C"); |
ccc1c731 | 567 | strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm); |
47622eef | 568 | info->builddate = mktime(&tmp_tm); |
e6673544 | 569 | setlocale(LC_TIME, ""); |
47622eef | 570 | } else { |
ccc1c731 | 571 | info->builddate = atol(line); |
47622eef | 572 | } |
ccc1c731 | 573 | } else if(strcmp(line, "%INSTALLDATE%") == 0) { |
d896527d | 574 | if(fgets(line, sizeof(line), fp) == NULL) { |
e2faeb46 AF |
575 | goto error; |
576 | } | |
ccc1c731 | 577 | _alpm_strtrim(line); |
47622eef | 578 | |
caea098c | 579 | char first = tolower((unsigned char)line[0]); |
47622eef | 580 | if(first > 'a' && first < 'z') { |
ed848b1c | 581 | struct tm tmp_tm = {0}; /* initialize to null in case of failure */ |
e6673544 | 582 | setlocale(LC_TIME, "C"); |
ccc1c731 | 583 | strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm); |
47622eef | 584 | info->installdate = mktime(&tmp_tm); |
e6673544 | 585 | setlocale(LC_TIME, ""); |
47622eef | 586 | } else { |
ccc1c731 | 587 | info->installdate = atol(line); |
47622eef | 588 | } |
ccc1c731 | 589 | } else if(strcmp(line, "%PACKAGER%") == 0) { |
d896527d | 590 | if(fgets(line, sizeof(line), fp) == NULL) { |
e2faeb46 AF |
591 | goto error; |
592 | } | |
ccc1c731 DM |
593 | STRDUP(info->packager, _alpm_strtrim(line), goto error); |
594 | } else if(strcmp(line, "%REASON%") == 0) { | |
d896527d | 595 | if(fgets(line, sizeof(line), fp) == NULL) { |
e2faeb46 AF |
596 | goto error; |
597 | } | |
f7192b59 | 598 | info->reason = (pmpkgreason_t)atol(_alpm_strtrim(line)); |
ccc1c731 | 599 | } else if(strcmp(line, "%SIZE%") == 0 || strcmp(line, "%CSIZE%") == 0) { |
e2faeb46 AF |
600 | /* NOTE: the CSIZE and SIZE fields both share the "size" field |
601 | * in the pkginfo_t struct. This can be done b/c CSIZE | |
602 | * is currently only used in sync databases, and SIZE is | |
603 | * only used in local databases. | |
604 | */ | |
d896527d | 605 | if(fgets(line, sizeof(line), fp) == NULL) { |
e2faeb46 AF |
606 | goto error; |
607 | } | |
ccc1c731 | 608 | info->size = atol(_alpm_strtrim(line)); |
5e12d3de DM |
609 | /* also store this value to isize if isize is unset */ |
610 | if(info->isize == 0) { | |
ccc1c731 | 611 | info->isize = info->size; |
5e12d3de | 612 | } |
ccc1c731 | 613 | } else if(strcmp(line, "%ISIZE%") == 0) { |
986409f9 | 614 | /* ISIZE (installed size) tag only appears in sync repositories, |
d37ad048 | 615 | * not the local one. */ |
d896527d | 616 | if(fgets(line, sizeof(line), fp) == NULL) { |
d37ad048 AG |
617 | goto error; |
618 | } | |
ccc1c731 DM |
619 | info->isize = atol(_alpm_strtrim(line)); |
620 | } else if(strcmp(line, "%MD5SUM%") == 0) { | |
e2faeb46 AF |
621 | /* MD5SUM tag only appears in sync repositories, |
622 | * not the local one. */ | |
d896527d | 623 | if(fgets(line, sizeof(line), fp) == NULL) { |
e2faeb46 AF |
624 | goto error; |
625 | } | |
ccc1c731 DM |
626 | STRDUP(info->md5sum, _alpm_strtrim(line), goto error); |
627 | } else if(strcmp(line, "%REPLACES%") == 0) { | |
d896527d | 628 | while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { |
ccc1c731 DM |
629 | char *linedup; |
630 | STRDUP(linedup, _alpm_strtrim(line), goto error); | |
631 | info->replaces = alpm_list_add(info->replaces, linedup); | |
e2faeb46 | 632 | } |
ccc1c731 | 633 | } else if(strcmp(line, "%FORCE%") == 0) { |
e2faeb46 AF |
634 | info->force = 1; |
635 | } | |
636 | } | |
637 | fclose(fp); | |
638 | fp = NULL; | |
639 | } | |
640 | ||
641 | /* FILES */ | |
642 | if(inforeq & INFRQ_FILES) { | |
0966c33a | 643 | snprintf(path, PATH_MAX, "%sfiles", pkgpath); |
170d6319 | 644 | if((fp = fopen(path, "r")) == NULL) { |
5c9eec55 | 645 | _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); |
e2faeb46 AF |
646 | goto error; |
647 | } | |
d896527d | 648 | while(fgets(line, sizeof(line), fp)) { |
e2faeb46 | 649 | _alpm_strtrim(line); |
ccc1c731 | 650 | if(strcmp(line, "%FILES%") == 0) { |
d896527d | 651 | while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { |
ccc1c731 DM |
652 | char *linedup; |
653 | STRDUP(linedup, _alpm_strtrim(line), goto error); | |
654 | info->files = alpm_list_add(info->files, linedup); | |
e2faeb46 | 655 | } |
ccc1c731 | 656 | } else if(strcmp(line, "%BACKUP%") == 0) { |
d896527d | 657 | while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { |
ccc1c731 DM |
658 | char *linedup; |
659 | STRDUP(linedup, _alpm_strtrim(line), goto error); | |
660 | info->backup = alpm_list_add(info->backup, linedup); | |
e2faeb46 AF |
661 | } |
662 | } | |
663 | } | |
664 | fclose(fp); | |
665 | fp = NULL; | |
666 | } | |
667 | ||
668 | /* DEPENDS */ | |
669 | if(inforeq & INFRQ_DEPENDS) { | |
0966c33a | 670 | snprintf(path, PATH_MAX, "%sdepends", pkgpath); |
170d6319 | 671 | if((fp = fopen(path, "r")) == NULL) { |
5c9eec55 | 672 | _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); |
e2faeb46 AF |
673 | goto error; |
674 | } | |
675 | while(!feof(fp)) { | |
d896527d | 676 | if(fgets(line, sizeof(line), fp) == NULL) { |
60de8ec9 AM |
677 | break; |
678 | } | |
e2faeb46 | 679 | _alpm_strtrim(line); |
ccc1c731 | 680 | if(strcmp(line, "%DEPENDS%") == 0) { |
d896527d | 681 | while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { |
b2914bf0 | 682 | pmdepend_t *dep = _alpm_splitdep(_alpm_strtrim(line)); |
c244cfec | 683 | info->depends = alpm_list_add(info->depends, dep); |
e2faeb46 | 684 | } |
ccc1c731 | 685 | } else if(strcmp(line, "%OPTDEPENDS%") == 0) { |
d896527d | 686 | while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { |
ccc1c731 DM |
687 | char *linedup; |
688 | STRDUP(linedup, _alpm_strtrim(line), goto error); | |
689 | info->optdepends = alpm_list_add(info->optdepends, linedup); | |
fc0e83f0 | 690 | } |
ccc1c731 | 691 | } else if(strcmp(line, "%CONFLICTS%") == 0) { |
d896527d | 692 | while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { |
ccc1c731 DM |
693 | char *linedup; |
694 | STRDUP(linedup, _alpm_strtrim(line), goto error); | |
695 | info->conflicts = alpm_list_add(info->conflicts, linedup); | |
e2faeb46 | 696 | } |
ccc1c731 | 697 | } else if(strcmp(line, "%PROVIDES%") == 0) { |
d896527d | 698 | while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { |
ccc1c731 DM |
699 | char *linedup; |
700 | STRDUP(linedup, _alpm_strtrim(line), goto error); | |
701 | info->provides = alpm_list_add(info->provides, linedup); | |
e2faeb46 | 702 | } |
13e21110 | 703 | } |
e2faeb46 AF |
704 | } |
705 | fclose(fp); | |
706 | fp = NULL; | |
707 | } | |
708 | ||
0c2cc108 NJ |
709 | /* DELTAS */ |
710 | if(inforeq & INFRQ_DELTAS) { | |
0966c33a | 711 | snprintf(path, PATH_MAX, "%sdeltas", pkgpath); |
0c2cc108 NJ |
712 | if((fp = fopen(path, "r"))) { |
713 | while(!feof(fp)) { | |
d896527d | 714 | if(fgets(line, sizeof(line), fp) == NULL) { |
60de8ec9 AM |
715 | break; |
716 | } | |
0c2cc108 | 717 | _alpm_strtrim(line); |
ccc1c731 | 718 | if(strcmp(line, "%DELTAS%") == 0) { |
d896527d | 719 | while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { |
b99bebc0 DM |
720 | pmdelta_t *delta = _alpm_delta_parse(line); |
721 | if(delta) { | |
722 | info->deltas = alpm_list_add(info->deltas, delta); | |
723 | } | |
0c2cc108 NJ |
724 | } |
725 | } | |
726 | } | |
727 | fclose(fp); | |
728 | fp = NULL; | |
729 | } | |
730 | } | |
731 | ||
e2faeb46 | 732 | /* INSTALL */ |
aa1c0ba9 | 733 | if(inforeq & INFRQ_SCRIPTLET) { |
0966c33a | 734 | snprintf(path, PATH_MAX, "%sinstall", pkgpath); |
29bf6814 | 735 | if(access(path, F_OK) == 0) { |
e2faeb46 AF |
736 | info->scriptlet = 1; |
737 | } | |
738 | } | |
739 | ||
740 | /* internal */ | |
741 | info->infolevel |= inforeq; | |
742 | ||
0966c33a | 743 | free(pkgpath); |
e2faeb46 AF |
744 | return(0); |
745 | ||
746 | error: | |
0966c33a | 747 | free(pkgpath); |
e2faeb46 AF |
748 | if(fp) { |
749 | fclose(fp); | |
750 | } | |
751 | return(-1); | |
752 | } | |
753 | ||
a73ad4f0 AM |
754 | int _alpm_db_prepare(pmdb_t *db, pmpkg_t *info) |
755 | { | |
756 | mode_t oldmask; | |
757 | int retval = 0; | |
758 | char *pkgpath = NULL; | |
759 | ||
34e1413d XC |
760 | if(checkdbdir(db) != 0) { |
761 | return(-1); | |
762 | } | |
a73ad4f0 | 763 | |
34e1413d | 764 | oldmask = umask(0000); |
a73ad4f0 AM |
765 | pkgpath = get_pkgpath(db, info); |
766 | ||
767 | if((retval = mkdir(pkgpath, 0755)) != 0) { | |
34e1413d XC |
768 | _alpm_log(PM_LOG_ERROR, _("could not create directory %s: %s\n"), |
769 | pkgpath, strerror(errno)); | |
a73ad4f0 AM |
770 | } |
771 | ||
772 | free(pkgpath); | |
773 | umask(oldmask); | |
774 | ||
775 | return(retval); | |
776 | } | |
777 | ||
a5f630fd | 778 | int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) |
e2faeb46 AF |
779 | { |
780 | FILE *fp = NULL; | |
781 | char path[PATH_MAX]; | |
782 | mode_t oldmask; | |
61670172 | 783 | alpm_list_t *lp = NULL; |
e2faeb46 AF |
784 | int retval = 0; |
785 | int local = 0; | |
0966c33a | 786 | char *pkgpath = NULL; |
e2faeb46 | 787 | |
da648bc2 AG |
788 | ALPM_LOG_FUNC; |
789 | ||
e2faeb46 AF |
790 | if(db == NULL || info == NULL) { |
791 | return(-1); | |
792 | } | |
793 | ||
0966c33a XC |
794 | pkgpath = get_pkgpath(db, info); |
795 | ||
e2faeb46 | 796 | /* make sure we have a sane umask */ |
a73ad4f0 | 797 | oldmask = umask(0022); |
e2faeb46 AF |
798 | |
799 | if(strcmp(db->treename, "local") == 0) { | |
800 | local = 1; | |
801 | } | |
af48c695 | 802 | |
e2faeb46 AF |
803 | /* DESC */ |
804 | if(inforeq & INFRQ_DESC) { | |
5c9eec55 | 805 | _alpm_log(PM_LOG_DEBUG, "writing %s-%s DESC information back to db\n", |
ea1fef69 | 806 | info->name, info->version); |
0966c33a | 807 | snprintf(path, PATH_MAX, "%sdesc", pkgpath); |
e2faeb46 | 808 | if((fp = fopen(path, "w")) == NULL) { |
5c9eec55 | 809 | _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); |
170d6319 | 810 | retval = -1; |
e2faeb46 AF |
811 | goto cleanup; |
812 | } | |
813 | fprintf(fp, "%%NAME%%\n%s\n\n" | |
af48c695 | 814 | "%%VERSION%%\n%s\n\n", info->name, info->version); |
ccc1c731 | 815 | if(info->desc) { |
af48c695 AG |
816 | fprintf(fp, "%%DESC%%\n" |
817 | "%s\n\n", info->desc); | |
e2faeb46 AF |
818 | } |
819 | if(info->groups) { | |
820 | fputs("%GROUPS%\n", fp); | |
821 | for(lp = info->groups; lp; lp = lp->next) { | |
822 | fprintf(fp, "%s\n", (char *)lp->data); | |
823 | } | |
824 | fprintf(fp, "\n"); | |
825 | } | |
b262ddb2 XC |
826 | if(info->replaces) { |
827 | fputs("%REPLACES%\n", fp); | |
828 | for(lp = info->replaces; lp; lp = lp->next) { | |
829 | fprintf(fp, "%s\n", (char *)lp->data); | |
830 | } | |
831 | fprintf(fp, "\n"); | |
832 | } | |
833 | if(info->force) { | |
834 | fprintf(fp, "%%FORCE%%\n\n"); | |
835 | } | |
e2faeb46 | 836 | if(local) { |
ccc1c731 | 837 | if(info->url) { |
e2faeb46 | 838 | fprintf(fp, "%%URL%%\n" |
af48c695 | 839 | "%s\n\n", info->url); |
e2faeb46 | 840 | } |
7f5dada8 | 841 | if(info->licenses) { |
e2faeb46 | 842 | fputs("%LICENSE%\n", fp); |
7f5dada8 | 843 | for(lp = info->licenses; lp; lp = lp->next) { |
e2faeb46 AF |
844 | fprintf(fp, "%s\n", (char *)lp->data); |
845 | } | |
846 | fprintf(fp, "\n"); | |
847 | } | |
ccc1c731 | 848 | if(info->arch) { |
e2faeb46 | 849 | fprintf(fp, "%%ARCH%%\n" |
af48c695 | 850 | "%s\n\n", info->arch); |
e2faeb46 | 851 | } |
47622eef | 852 | if(info->builddate) { |
e2faeb46 | 853 | fprintf(fp, "%%BUILDDATE%%\n" |
7965345d | 854 | "%ld\n\n", info->builddate); |
e2faeb46 | 855 | } |
47622eef | 856 | if(info->installdate) { |
e2faeb46 | 857 | fprintf(fp, "%%INSTALLDATE%%\n" |
7965345d | 858 | "%ld\n\n", info->installdate); |
e2faeb46 | 859 | } |
ccc1c731 | 860 | if(info->packager) { |
e2faeb46 | 861 | fprintf(fp, "%%PACKAGER%%\n" |
af48c695 | 862 | "%s\n\n", info->packager); |
e2faeb46 | 863 | } |
0669c9bf | 864 | if(info->isize) { |
38784a7e | 865 | /* only write installed size, csize is irrelevant once installed */ |
e2faeb46 | 866 | fprintf(fp, "%%SIZE%%\n" |
9519d22d | 867 | "%jd\n\n", (intmax_t)info->isize); |
e2faeb46 AF |
868 | } |
869 | if(info->reason) { | |
870 | fprintf(fp, "%%REASON%%\n" | |
af48c695 | 871 | "%u\n\n", info->reason); |
e2faeb46 AF |
872 | } |
873 | } else { | |
874 | if(info->size) { | |
875 | fprintf(fp, "%%CSIZE%%\n" | |
9519d22d | 876 | "%jd\n\n", (intmax_t)info->size); |
e2faeb46 | 877 | } |
986409f9 AG |
878 | if(info->isize) { |
879 | fprintf(fp, "%%ISIZE%%\n" | |
9519d22d | 880 | "%jd\n\n", (intmax_t)info->isize); |
d37ad048 | 881 | } |
ba67fdae | 882 | if(info->md5sum) { |
e2faeb46 | 883 | fprintf(fp, "%%MD5SUM%%\n" |
af48c695 | 884 | "%s\n\n", info->md5sum); |
e2faeb46 AF |
885 | } |
886 | } | |
887 | fclose(fp); | |
888 | fp = NULL; | |
889 | } | |
890 | ||
891 | /* FILES */ | |
892 | if(local && (inforeq & INFRQ_FILES)) { | |
5c9eec55 | 893 | _alpm_log(PM_LOG_DEBUG, "writing %s-%s FILES information back to db\n", |
ea1fef69 | 894 | info->name, info->version); |
0966c33a | 895 | snprintf(path, PATH_MAX, "%sfiles", pkgpath); |
e2faeb46 | 896 | if((fp = fopen(path, "w")) == NULL) { |
5c9eec55 | 897 | _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); |
e2faeb46 AF |
898 | retval = -1; |
899 | goto cleanup; | |
900 | } | |
901 | if(info->files) { | |
902 | fprintf(fp, "%%FILES%%\n"); | |
903 | for(lp = info->files; lp; lp = lp->next) { | |
904 | fprintf(fp, "%s\n", (char *)lp->data); | |
905 | } | |
906 | fprintf(fp, "\n"); | |
907 | } | |
908 | if(info->backup) { | |
909 | fprintf(fp, "%%BACKUP%%\n"); | |
910 | for(lp = info->backup; lp; lp = lp->next) { | |
911 | fprintf(fp, "%s\n", (char *)lp->data); | |
912 | } | |
913 | fprintf(fp, "\n"); | |
914 | } | |
915 | fclose(fp); | |
916 | fp = NULL; | |
917 | } | |
918 | ||
919 | /* DEPENDS */ | |
920 | if(inforeq & INFRQ_DEPENDS) { | |
5c9eec55 | 921 | _alpm_log(PM_LOG_DEBUG, "writing %s-%s DEPENDS information back to db\n", |
ea1fef69 | 922 | info->name, info->version); |
0966c33a | 923 | snprintf(path, PATH_MAX, "%sdepends", pkgpath); |
e2faeb46 | 924 | if((fp = fopen(path, "w")) == NULL) { |
5c9eec55 | 925 | _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); |
e2faeb46 AF |
926 | retval = -1; |
927 | goto cleanup; | |
928 | } | |
929 | if(info->depends) { | |
930 | fputs("%DEPENDS%\n", fp); | |
931 | for(lp = info->depends; lp; lp = lp->next) { | |
4da70d80 | 932 | char *depstring = alpm_dep_compute_string(lp->data); |
c244cfec DM |
933 | fprintf(fp, "%s\n", depstring); |
934 | free(depstring); | |
e2faeb46 AF |
935 | } |
936 | fprintf(fp, "\n"); | |
937 | } | |
fc0e83f0 DM |
938 | if(info->optdepends) { |
939 | fputs("%OPTDEPENDS%\n", fp); | |
940 | for(lp = info->optdepends; lp; lp = lp->next) { | |
941 | fprintf(fp, "%s\n", (char *)lp->data); | |
942 | } | |
943 | fprintf(fp, "\n"); | |
944 | } | |
e2faeb46 AF |
945 | if(info->conflicts) { |
946 | fputs("%CONFLICTS%\n", fp); | |
947 | for(lp = info->conflicts; lp; lp = lp->next) { | |
948 | fprintf(fp, "%s\n", (char *)lp->data); | |
949 | } | |
950 | fprintf(fp, "\n"); | |
951 | } | |
952 | if(info->provides) { | |
953 | fputs("%PROVIDES%\n", fp); | |
954 | for(lp = info->provides; lp; lp = lp->next) { | |
955 | fprintf(fp, "%s\n", (char *)lp->data); | |
956 | } | |
957 | fprintf(fp, "\n"); | |
958 | } | |
e2faeb46 AF |
959 | fclose(fp); |
960 | fp = NULL; | |
961 | } | |
962 | ||
963 | /* INSTALL */ | |
d37ad048 | 964 | /* nothing needed here (script is automatically extracted) */ |
e2faeb46 AF |
965 | |
966 | cleanup: | |
967 | umask(oldmask); | |
0966c33a | 968 | free(pkgpath); |
e2faeb46 AF |
969 | |
970 | if(fp) { | |
971 | fclose(fp); | |
972 | } | |
973 | ||
974 | return(retval); | |
975 | } | |
976 | ||
977 | int _alpm_db_remove(pmdb_t *db, pmpkg_t *info) | |
978 | { | |
0966c33a XC |
979 | int ret = 0; |
980 | char *pkgpath = NULL; | |
e2faeb46 | 981 | |
da648bc2 AG |
982 | ALPM_LOG_FUNC; |
983 | ||
e2faeb46 | 984 | if(db == NULL || info == NULL) { |
e8275fa9 | 985 | RET_ERR(PM_ERR_DB_NULL, -1); |
e2faeb46 AF |
986 | } |
987 | ||
0966c33a | 988 | pkgpath = get_pkgpath(db, info); |
e2faeb46 | 989 | |
0966c33a XC |
990 | ret = _alpm_rmrf(pkgpath); |
991 | free(pkgpath); | |
992 | if(ret != 0) { | |
993 | ret = -1; | |
994 | } | |
995 | return(ret); | |
e2faeb46 AF |
996 | } |
997 | ||
998 | /* vim: set ts=2 sw=2 noet: */ |