00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "config.h"
00021
00022 #include <stdlib.h>
00023 #include <errno.h>
00024 #include <time.h>
00025 #include <string.h>
00026 #include <limits.h>
00027 #include <sys/types.h>
00028 #include <sys/stat.h>
00029 #include <unistd.h>
00030
00031
00032 #include <archive.h>
00033 #include <archive_entry.h>
00034
00035
00036 #include "add.h"
00037 #include "alpm_list.h"
00038 #include "trans.h"
00039 #include "util.h"
00040 #include "error.h"
00041 #include "cache.h"
00042 #include "log.h"
00043 #include "backup.h"
00044 #include "package.h"
00045 #include "db.h"
00046 #include "conflict.h"
00047 #include "deps.h"
00048 #include "remove.h"
00049 #include "handle.h"
00050
00051 int _alpm_add_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name)
00052 {
00053 pmpkg_t *pkg = NULL;
00054 const char *pkgname, *pkgver;
00055 alpm_list_t *i;
00056
00057 ALPM_LOG_FUNC;
00058
00059 ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
00060 ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
00061 ASSERT(name != NULL && strlen(name) != 0, RET_ERR(PM_ERR_WRONG_ARGS, -1));
00062
00063 _alpm_log(PM_LOG_DEBUG, "loading target '%s'\n", name);
00064
00065 if(alpm_pkg_load(name, 1, &pkg) != 0) {
00066 goto error;
00067 }
00068 pkgname = alpm_pkg_get_name(pkg);
00069 pkgver = alpm_pkg_get_version(pkg);
00070
00071 if(trans->type != PM_TRANS_TYPE_UPGRADE) {
00072
00073 if(_alpm_db_get_pkgfromcache(db, pkgname)) {
00074 pm_errno = PM_ERR_PKG_INSTALLED;
00075 goto error;
00076 }
00077 }
00078
00079
00080
00081 for(i = trans->packages; i; i = i->next) {
00082 pmpkg_t *pkg = i->data;
00083 if(strcmp(pkg->name, pkgname) == 0) {
00084 if(_alpm_versioncmp(pkg->version, pkgver) < 0) {
00085 pmpkg_t *newpkg;
00086 _alpm_log(PM_LOG_WARNING, _("replacing older version %s-%s by %s in target list\n"),
00087 pkg->name, pkg->version, pkgver);
00088 if((newpkg = _alpm_pkg_load(name, 1)) == NULL) {
00089
00090 goto error;
00091 }
00092 _alpm_pkg_free(i->data);
00093 i->data = newpkg;
00094 } else {
00095 _alpm_log(PM_LOG_WARNING, _("newer version %s-%s is in the target list -- skipping\n"),
00096 pkg->name, pkg->version);
00097 }
00098 return(0);
00099 }
00100 }
00101
00102 if(trans->flags & PM_TRANS_FLAG_ALLDEPS) {
00103 pkg->reason = PM_PKG_REASON_DEPEND;
00104 }
00105
00106
00107 trans->packages = alpm_list_add(trans->packages, pkg);
00108
00109 return(0);
00110
00111 error:
00112 _alpm_pkg_free(pkg);
00113 return(-1);
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
00126 {
00127 alpm_list_t *lp = NULL;
00128
00129 ALPM_LOG_FUNC;
00130
00131 ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
00132 ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
00133
00134
00135
00136 if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
00137 EVENT(trans, PM_TRANS_EVT_CHECKDEPS_START, NULL, NULL);
00138
00139
00140 _alpm_log(PM_LOG_DEBUG, "looking for unsatisfied dependencies\n");
00141 lp = alpm_checkdeps(db, trans->type == PM_TRANS_TYPE_UPGRADE, NULL, trans->packages);
00142 if(lp != NULL) {
00143 if(data) {
00144 *data = lp;
00145 } else {
00146 alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free);
00147 alpm_list_free(lp);
00148 }
00149 RET_ERR(PM_ERR_UNSATISFIED_DEPS, -1);
00150 }
00151
00152
00153 _alpm_log(PM_LOG_DEBUG, "looking for conflicts\n");
00154 alpm_list_t *inner = _alpm_innerconflicts(trans->packages);
00155 alpm_list_t *outer = _alpm_outerconflicts(db, trans->packages);
00156 lp = alpm_list_join(inner, outer);
00157
00158
00159
00160 if(lp != NULL) {
00161 if(data) {
00162 *data = lp;
00163 } else {
00164 FREELIST(lp);
00165 }
00166 if(inner) {
00167 _alpm_log(PM_LOG_ERROR, _("conflicting packages were found in the target list\n"));
00168 _alpm_log(PM_LOG_ERROR, _("you cannot install two conflicting packages at the same time\n"));
00169 }
00170 if(outer) {
00171 _alpm_log(PM_LOG_ERROR, _("replacing packages with -A and -U is not supported yet\n"));
00172 _alpm_log(PM_LOG_ERROR, _("you can replace packages manually using -Rd and -U\n"));
00173 }
00174 RET_ERR(PM_ERR_CONFLICTING_DEPS, -1);
00175 }
00176
00177
00178 _alpm_log(PM_LOG_DEBUG, "sorting by dependencies\n");
00179 lp = _alpm_sortbydeps(trans->packages, PM_TRANS_TYPE_ADD);
00180
00181 alpm_list_free(trans->packages);
00182 trans->packages = lp;
00183
00184 EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);
00185 }
00186
00187
00188 if(!(trans->flags & PM_TRANS_FLAG_FORCE)) {
00189 EVENT(trans, PM_TRANS_EVT_FILECONFLICTS_START, NULL, NULL);
00190
00191 _alpm_log(PM_LOG_DEBUG, "looking for file conflicts\n");
00192 lp = _alpm_db_find_fileconflicts(db, trans, handle->root);
00193 if(lp != NULL) {
00194 if(data) {
00195 *data = lp;
00196 } else {
00197 alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_fileconflict_free);
00198 alpm_list_free(lp);
00199 }
00200 RET_ERR(PM_ERR_FILE_CONFLICTS, -1);
00201 }
00202
00203 EVENT(trans, PM_TRANS_EVT_FILECONFLICTS_DONE, NULL, NULL);
00204 }
00205
00206 return(0);
00207 }
00208
00209 static int upgrade_remove(pmpkg_t *oldpkg, pmpkg_t *newpkg, pmtrans_t *trans, pmdb_t *db) {
00210
00211
00212
00213
00214 pmtrans_t *tr = _alpm_trans_new();
00215 _alpm_log(PM_LOG_DEBUG, "removing old package first (%s-%s)\n",
00216 oldpkg->name, oldpkg->version);
00217
00218 if(!tr) {
00219 RET_ERR(PM_ERR_TRANS_ABORT, -1);
00220 }
00221
00222 if(_alpm_trans_init(tr, PM_TRANS_TYPE_REMOVEUPGRADE, trans->flags,
00223 NULL, NULL, NULL) == -1) {
00224 _alpm_trans_free(tr);
00225 tr = NULL;
00226 RET_ERR(PM_ERR_TRANS_ABORT, -1);
00227 }
00228
00229 if(_alpm_remove_loadtarget(tr, db, newpkg->name) == -1) {
00230 _alpm_trans_free(tr);
00231 tr = NULL;
00232 RET_ERR(PM_ERR_TRANS_ABORT, -1);
00233 }
00234
00235
00236 tr->skip_remove = alpm_list_strdup(trans->skip_remove);
00237 const alpm_list_t *b;
00238
00239
00240
00241 alpm_list_t *old_noupgrade = alpm_list_strdup(handle->noupgrade);
00242
00243 alpm_list_t *filelist = alpm_pkg_get_files(newpkg);
00244 for(b = alpm_pkg_get_backup(newpkg); b; b = b->next) {
00245 char *backup = _alpm_backup_file(b->data);
00246
00247 if(!alpm_list_find_str(filelist, backup)) {
00248 continue;
00249 }
00250 _alpm_log(PM_LOG_DEBUG, "adding %s to the NoUpgrade array temporarily\n",
00251 backup);
00252 handle->noupgrade = alpm_list_add(handle->noupgrade,
00253 backup);
00254 }
00255
00256
00257
00258
00259
00260 #if 0
00261
00262 for(b = alpm_pkg_get_backup(oldpkg); b; b = b->next) {
00263 char *backup = _alpm_backup_file(b->data);
00264
00265 if(!alpm_list_find_ptr(handle->noupgrade, backup)) {
00266 _alpm_log(PM_LOG_DEBUG, "adding %s to the NoUpgrade array temporarily\n",
00267 backup);
00268 handle->noupgrade = alpm_list_add(handle->noupgrade,
00269 backup);
00270 }
00271 }
00272 #endif
00273
00274 int ret = _alpm_remove_commit(tr, db);
00275
00276 _alpm_trans_free(tr);
00277 tr = NULL;
00278
00279
00280 FREELIST(handle->noupgrade);
00281 handle->noupgrade = old_noupgrade;
00282
00283 if(ret == -1) {
00284 RET_ERR(PM_ERR_TRANS_ABORT, -1);
00285 }
00286
00287 return(0);
00288 }
00289
00290 static int extract_single_file(struct archive *archive,
00291 struct archive_entry *entry, pmpkg_t *newpkg, pmpkg_t *oldpkg,
00292 pmtrans_t *trans, pmdb_t *db)
00293 {
00294 const char *entryname;
00295 mode_t entrymode;
00296 char filename[PATH_MAX];
00297 int needbackup = 0, notouch = 0;
00298 char *hash_orig = NULL;
00299 const int archive_flags = ARCHIVE_EXTRACT_OWNER |
00300 ARCHIVE_EXTRACT_PERM |
00301 ARCHIVE_EXTRACT_TIME;
00302 int errors = 0;
00303
00304 entryname = archive_entry_pathname(entry);
00305 entrymode = archive_entry_mode(entry);
00306
00307 memset(filename, 0, PATH_MAX);
00308
00309 if(strcmp(entryname, ".INSTALL") == 0) {
00310
00311 snprintf(filename, PATH_MAX, "%s/%s-%s/install", db->path,
00312 newpkg->name, newpkg->version);
00313 archive_entry_set_mode(entry, 0644);
00314 } else if(strcmp(entryname, ".CHANGELOG") == 0) {
00315
00316 snprintf(filename, PATH_MAX, "%s/%s-%s/changelog", db->path,
00317 newpkg->name, newpkg->version);
00318 archive_entry_set_mode(entry, 0644);
00319 } else if(*entryname == '.') {
00320
00321
00322 _alpm_log(PM_LOG_DEBUG, "skipping extraction of '%s'\n", entryname);
00323 archive_read_data_skip(archive);
00324 return(0);
00325 } else {
00326
00327 snprintf(filename, PATH_MAX, "%s%s", handle->root, entryname);
00328 }
00329
00330
00331 if(alpm_list_find_str(handle->noextract, entryname)) {
00332 _alpm_log(PM_LOG_DEBUG, "%s is in NoExtract, skipping extraction\n",
00333 entryname);
00334 alpm_logaction("note: %s is in NoExtract, skipping extraction\n",
00335 entryname);
00336 archive_read_data_skip(archive);
00337 return(0);
00338 }
00339
00340
00341 if(alpm_list_find_str(trans->skip_add, filename)) {
00342 _alpm_log(PM_LOG_DEBUG, "%s is in trans->skip_add, skipping extraction\n", entryname);
00343 archive_read_data_skip(archive);
00344 return(0);
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 struct stat lsbuf;
00367 if(_alpm_lstat(filename, &lsbuf) != 0) {
00368
00369 } else {
00370
00371 struct stat sbuf;
00372 stat(filename, &sbuf);
00373
00374 if(S_ISDIR(lsbuf.st_mode) && S_ISDIR(entrymode)) {
00375
00376 if(lsbuf.st_mode != entrymode) {
00377
00378 int mask = 07777;
00379 _alpm_log(PM_LOG_WARNING, _("directory permissions differ on %s\n"
00380 "filesystem: %o package: %o\n"), entryname, lsbuf.st_mode & mask,
00381 entrymode & mask);
00382 alpm_logaction("warning: directory permissions differ on %s\n"
00383 "filesystem: %o package: %o\n", entryname, lsbuf.st_mode & mask,
00384 entrymode & mask);
00385 }
00386 _alpm_log(PM_LOG_DEBUG, "extract: skipping dir extraction of %s\n",
00387 entryname);
00388 archive_read_data_skip(archive);
00389 return(0);
00390 } else if(S_ISDIR(lsbuf.st_mode) && S_ISLNK(entrymode)) {
00391
00392 _alpm_log(PM_LOG_DEBUG, "extract: skipping symlink extraction of %s\n",
00393 entryname);
00394 archive_read_data_skip(archive);
00395 return(0);
00396 } else if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(entrymode)) {
00397
00398 if(S_ISDIR(sbuf.st_mode)) {
00399
00400 _alpm_log(PM_LOG_DEBUG, "extract: skipping symlink overwrite of %s\n",
00401 entryname);
00402 archive_read_data_skip(archive);
00403 return(0);
00404 } else {
00405
00406 _alpm_log(PM_LOG_ERROR, _("extract: symlink %s does not point to dir\n"),
00407 entryname);
00408 archive_read_data_skip(archive);
00409 return(1);
00410 }
00411 } else if(S_ISDIR(lsbuf.st_mode) && S_ISREG(entrymode)) {
00412
00413 _alpm_log(PM_LOG_ERROR, _("extract: not overwriting dir with file %s\n"),
00414 entryname);
00415 archive_read_data_skip(archive);
00416 return(1);
00417 } else if(S_ISREG(lsbuf.st_mode) && S_ISDIR(entrymode)) {
00418
00419 _alpm_log(PM_LOG_DEBUG, "extract: overwriting file with dir %s\n",
00420 entryname);
00421 } else if(S_ISREG(entrymode)) {
00422
00423
00424 if(alpm_list_find_str(handle->noupgrade, entryname)) {
00425 notouch = 1;
00426 } else {
00427
00428
00429 if(alpm_list_find_str(alpm_pkg_get_backup(newpkg), entryname) != NULL) {
00430 needbackup = 1;
00431 }
00432
00433
00434 if(oldpkg) {
00435 hash_orig = _alpm_needbackup(entryname, alpm_pkg_get_backup(oldpkg));
00436 if(hash_orig) {
00437 needbackup = 1;
00438 }
00439 }
00440
00441
00442 if(needbackup && !hash_orig) {
00443 hash_orig = strdup("");
00444 }
00445 }
00446 }
00447
00448
00449 }
00450
00451 if(needbackup) {
00452 char *tempfile = NULL;
00453 char *hash_local = NULL, *hash_pkg = NULL;
00454 int fd;
00455
00456
00457 tempfile = strdup("/tmp/alpm_XXXXXX");
00458 fd = mkstemp(tempfile);
00459
00460 archive_entry_set_pathname(entry, tempfile);
00461
00462 int ret = archive_read_extract(archive, entry, archive_flags);
00463 if(ret == ARCHIVE_WARN) {
00464
00465 _alpm_log(PM_LOG_DEBUG, "warning extracting %s (%s)\n",
00466 entryname, archive_error_string(archive));
00467 } else if(ret != ARCHIVE_OK) {
00468 _alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)\n"),
00469 entryname, archive_error_string(archive));
00470 alpm_logaction("error: could not extract %s (%s)\n",
00471 entryname, archive_error_string(archive));
00472 unlink(tempfile);
00473 FREE(hash_orig);
00474 close(fd);
00475 return(1);
00476 }
00477
00478 hash_local = alpm_get_md5sum(filename);
00479 hash_pkg = alpm_get_md5sum(tempfile);
00480
00481
00482
00483 alpm_list_t *backups;
00484 for(backups = alpm_pkg_get_backup(newpkg); backups;
00485 backups = alpm_list_next(backups)) {
00486 char *oldbackup = alpm_list_getdata(backups);
00487 if(!oldbackup || strcmp(oldbackup, entryname) != 0) {
00488 continue;
00489 }
00490 char *backup = NULL;
00491
00492 int backup_len = strlen(oldbackup) + 34;
00493 backup = malloc(backup_len);
00494 if(!backup) {
00495 RET_ERR(PM_ERR_MEMORY, -1);
00496 }
00497
00498 sprintf(backup, "%s\t%s", oldbackup, hash_pkg);
00499 backup[backup_len-1] = '\0';
00500 FREE(oldbackup);
00501 backups->data = backup;
00502 }
00503
00504 _alpm_log(PM_LOG_DEBUG, "checking hashes for %s\n", entryname);
00505 _alpm_log(PM_LOG_DEBUG, "current: %s\n", hash_local);
00506 _alpm_log(PM_LOG_DEBUG, "new: %s\n", hash_pkg);
00507 _alpm_log(PM_LOG_DEBUG, "original: %s\n", hash_orig);
00508
00509 if(!oldpkg) {
00510
00511
00512 if(strcmp(hash_local, hash_pkg) != 0) {
00513 char newpath[PATH_MAX];
00514 snprintf(newpath, PATH_MAX, "%s.pacorig", filename);
00515
00516
00517 if(rename(filename, newpath)) {
00518 archive_entry_set_pathname(entry, filename);
00519 _alpm_log(PM_LOG_ERROR, _("could not rename %s (%s)\n"), filename, strerror(errno));
00520 alpm_logaction("error: could not rename %s (%s)\n", filename, strerror(errno));
00521 errors++;
00522 } else {
00523
00524 if(_alpm_copyfile(tempfile, filename)) {
00525 archive_entry_set_pathname(entry, filename);
00526 _alpm_log(PM_LOG_ERROR, _("could not copy tempfile to %s (%s)\n"), filename, strerror(errno));
00527 alpm_logaction("error: could not copy tempfile to %s (%s)\n", filename, strerror(errno));
00528 errors++;
00529 } else {
00530 archive_entry_set_pathname(entry, filename);
00531 _alpm_log(PM_LOG_WARNING, _("%s saved as %s\n"), filename, newpath);
00532 alpm_logaction("warning: %s saved as %s\n", filename, newpath);
00533 }
00534 }
00535 }
00536 } else if(hash_orig) {
00537
00538
00539 if(strcmp(hash_orig, hash_local) == 0) {
00540
00541 if(strcmp(hash_orig, hash_pkg) != 0) {
00542 _alpm_log(PM_LOG_DEBUG, "action: installing new file: %s\n",
00543 entryname);
00544
00545 if(_alpm_copyfile(tempfile, filename)) {
00546 _alpm_log(PM_LOG_ERROR, _("could not copy tempfile to %s (%s)\n"), filename, strerror(errno));
00547 errors++;
00548 }
00549 archive_entry_set_pathname(entry, filename);
00550 } else {
00551
00552
00553 _alpm_log(PM_LOG_DEBUG, "action: leaving existing file in place\n");
00554 }
00555 } else if(strcmp(hash_orig, hash_pkg) == 0) {
00556
00557
00558
00559 _alpm_log(PM_LOG_DEBUG, "action: leaving existing file in place\n");
00560 } else if(strcmp(hash_local, hash_pkg) == 0) {
00561
00562
00563
00564 _alpm_log(PM_LOG_DEBUG, "action: leaving existing file in place\n");
00565 } else {
00566 char newpath[PATH_MAX];
00567 _alpm_log(PM_LOG_DEBUG, "action: keeping current file and installing new one with .pacnew ending\n");
00568 snprintf(newpath, PATH_MAX, "%s.pacnew", filename);
00569 if(_alpm_copyfile(tempfile, newpath)) {
00570 _alpm_log(PM_LOG_ERROR, _("could not install %s as %s: %s\n"), filename, newpath, strerror(errno));
00571 alpm_logaction("error: could not install %s as %s: %s\n", filename, newpath, strerror(errno));
00572 } else {
00573 _alpm_log(PM_LOG_WARNING, _("%s installed as %s\n"), filename, newpath);
00574 alpm_logaction("warning: %s installed as %s\n", filename, newpath);
00575 }
00576 }
00577 }
00578
00579 FREE(hash_local);
00580 FREE(hash_pkg);
00581 FREE(hash_orig);
00582 unlink(tempfile);
00583 FREE(tempfile);
00584 close(fd);
00585 } else {
00586
00587 if(notouch) {
00588
00589 _alpm_log(PM_LOG_DEBUG, "%s is in NoUpgrade -- skipping\n", filename);
00590 _alpm_log(PM_LOG_WARNING, _("extracting %s as %s.pacnew\n"), filename, filename);
00591 alpm_logaction("warning: extracting %s as %s.pacnew\n", filename, filename);
00592 strncat(filename, ".pacnew", PATH_MAX - strlen(filename));
00593 } else {
00594 _alpm_log(PM_LOG_DEBUG, "extracting %s\n", filename);
00595 }
00596
00597 if(trans->flags & PM_TRANS_FLAG_FORCE) {
00598
00599
00600
00601 unlink(filename);
00602 }
00603
00604 archive_entry_set_pathname(entry, filename);
00605
00606 int ret = archive_read_extract(archive, entry, archive_flags);
00607 if(ret == ARCHIVE_WARN) {
00608
00609 _alpm_log(PM_LOG_DEBUG, "warning extracting %s (%s)\n",
00610 entryname, archive_error_string(archive));
00611 } else if(ret != ARCHIVE_OK) {
00612 _alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)\n"),
00613 entryname, archive_error_string(archive));
00614 alpm_logaction("error: could not extract %s (%s)\n",
00615 entryname, archive_error_string(archive));
00616 return(1);
00617 }
00618
00619
00620 alpm_list_t *b;
00621 for(b = alpm_pkg_get_backup(newpkg); b; b = b->next) {
00622 char *backup = NULL, *hash = NULL;
00623 char *oldbackup = alpm_list_getdata(b);
00624
00625 int backup_len = strlen(oldbackup) + 34;
00626
00627 if(!oldbackup || strcmp(oldbackup, entryname) != 0) {
00628 continue;
00629 }
00630 _alpm_log(PM_LOG_DEBUG, "appending backup entry for %s\n", filename);
00631
00632 hash = alpm_get_md5sum(filename);
00633 backup = malloc(backup_len);
00634 if(!backup) {
00635 RET_ERR(PM_ERR_MEMORY, -1);
00636 }
00637
00638 sprintf(backup, "%s\t%s", oldbackup, hash);
00639 backup[backup_len-1] = '\0';
00640 FREE(hash);
00641 FREE(oldbackup);
00642 b->data = backup;
00643 }
00644 }
00645 return(errors);
00646 }
00647
00648 static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
00649 pmtrans_t *trans, pmdb_t *db)
00650 {
00651 int i, ret = 0, errors = 0;
00652 struct archive *archive;
00653 struct archive_entry *entry;
00654 char cwd[PATH_MAX] = "";
00655 char scriptlet[PATH_MAX+1];
00656 int is_upgrade = 0;
00657 double percent = 0.0;
00658 pmpkg_t *oldpkg = NULL;
00659
00660 snprintf(scriptlet, PATH_MAX, "%s%s-%s/install", db->path,
00661 alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
00662
00663
00664 pmpkg_t *local = _alpm_db_get_pkgfromcache(db, newpkg->name);
00665 if(local) {
00666 is_upgrade = 1;
00667
00668 EVENT(trans, PM_TRANS_EVT_UPGRADE_START, newpkg, NULL);
00669 _alpm_log(PM_LOG_DEBUG, "upgrading package %s-%s\n",
00670 newpkg->name, newpkg->version);
00671
00672
00673 oldpkg = _alpm_pkg_dup(local);
00674
00675 if(trans->flags & PM_TRANS_FLAG_ALLDEPS) {
00676 newpkg->reason = PM_PKG_REASON_DEPEND;
00677 } else {
00678 newpkg->reason = alpm_pkg_get_reason(local);
00679 }
00680
00681
00682 if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
00683 _alpm_runscriptlet(handle->root, newpkg->origin_data.file,
00684 "pre_upgrade", newpkg->version, oldpkg->version, trans);
00685 }
00686 } else {
00687 is_upgrade = 0;
00688
00689 EVENT(trans, PM_TRANS_EVT_ADD_START, newpkg, NULL);
00690 _alpm_log(PM_LOG_DEBUG, "adding package %s-%s\n",
00691 newpkg->name, newpkg->version);
00692
00693
00694 if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
00695 _alpm_runscriptlet(handle->root, newpkg->origin_data.file,
00696 "pre_install", newpkg->version, NULL, trans);
00697 }
00698 }
00699
00700 if(oldpkg) {
00701
00702 int ret = upgrade_remove(oldpkg, newpkg, trans, db);
00703 if(ret != 0) {
00704 return(ret);
00705 }
00706 }
00707
00708 if(!(trans->flags & PM_TRANS_FLAG_DBONLY)) {
00709 _alpm_log(PM_LOG_DEBUG, "extracting files\n");
00710
00711 if ((archive = archive_read_new()) == NULL) {
00712 RET_ERR(PM_ERR_LIBARCHIVE_ERROR, -1);
00713 }
00714
00715 archive_read_support_compression_all(archive);
00716 archive_read_support_format_all(archive);
00717
00718 if(archive_read_open_filename(archive, newpkg->origin_data.file,
00719 ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
00720 RET_ERR(PM_ERR_PKG_OPEN, -1);
00721 }
00722
00723
00724 if(getcwd(cwd, PATH_MAX) == NULL) {
00725 _alpm_log(PM_LOG_ERROR, _("could not get current working directory\n"));
00726 cwd[0] = 0;
00727 }
00728
00729
00730 chdir(handle->root);
00731
00732
00733 if(is_upgrade) {
00734 PROGRESS(trans, PM_TRANS_PROGRESS_UPGRADE_START,
00735 alpm_pkg_get_name(newpkg), 0, pkg_count, pkg_current);
00736 } else {
00737 PROGRESS(trans, PM_TRANS_PROGRESS_ADD_START,
00738 alpm_pkg_get_name(newpkg), 0, pkg_count, pkg_current);
00739 }
00740
00741 for(i = 0; archive_read_next_header(archive, &entry) == ARCHIVE_OK; i++) {
00742 if(newpkg->size != 0) {
00743
00744
00745
00746 unsigned long pos = archive_position_compressed(archive);
00747 percent = (double)pos / (double)newpkg->size;
00748 _alpm_log(PM_LOG_DEBUG, "decompression progress: %f%% (%ld / %ld)\n",
00749 percent*100.0, pos, newpkg->size);
00750 if(percent >= 1.0) {
00751 percent = 1.0;
00752 }
00753 }
00754
00755 if(is_upgrade) {
00756 PROGRESS(trans, PM_TRANS_PROGRESS_UPGRADE_START,
00757 alpm_pkg_get_name(newpkg), (int)(percent * 100), pkg_count,
00758 pkg_current);
00759 } else {
00760 PROGRESS(trans, PM_TRANS_PROGRESS_ADD_START,
00761 alpm_pkg_get_name(newpkg), (int)(percent * 100), pkg_count,
00762 pkg_current);
00763 }
00764
00765
00766 errors += extract_single_file(archive, entry, newpkg, oldpkg,
00767 trans, db);
00768 }
00769 archive_read_finish(archive);
00770
00771
00772 if(strlen(cwd)) {
00773 chdir(cwd);
00774 }
00775
00776 if(errors) {
00777 ret = 1;
00778 if(is_upgrade) {
00779 _alpm_log(PM_LOG_ERROR, _("problem occurred while upgrading %s\n"),
00780 newpkg->name);
00781 alpm_logaction("error: problem occurred while upgrading %s\n",
00782 newpkg->name);
00783 } else {
00784 _alpm_log(PM_LOG_ERROR, _("problem occurred while installing %s\n"),
00785 newpkg->name);
00786 alpm_logaction("error: problem occurred while installing %s\n",
00787 newpkg->name);
00788 }
00789 }
00790 }
00791
00792
00793 newpkg->installdate = time(NULL);
00794
00795 _alpm_log(PM_LOG_DEBUG, "updating database\n");
00796 _alpm_log(PM_LOG_DEBUG, "adding database entry '%s'\n", newpkg->name);
00797
00798 if(_alpm_db_write(db, newpkg, INFRQ_ALL)) {
00799 _alpm_log(PM_LOG_ERROR, _("could not update database entry %s-%s\n"),
00800 alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
00801 alpm_logaction("error: could not update database entry %s-%s\n",
00802 alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
00803 RET_ERR(PM_ERR_DB_WRITE, -1);
00804 }
00805
00806 if(_alpm_db_add_pkgincache(db, newpkg) == -1) {
00807 _alpm_log(PM_LOG_ERROR, _("could not add entry '%s' in cache\n"),
00808 alpm_pkg_get_name(newpkg));
00809 }
00810
00811 if(is_upgrade) {
00812 PROGRESS(trans, PM_TRANS_PROGRESS_UPGRADE_START,
00813 alpm_pkg_get_name(newpkg), 100, pkg_count, pkg_current);
00814 } else {
00815 PROGRESS(trans, PM_TRANS_PROGRESS_ADD_START,
00816 alpm_pkg_get_name(newpkg), 100, pkg_count, pkg_current);
00817 }
00818 EVENT(trans, PM_TRANS_EVT_EXTRACT_DONE, NULL, NULL);
00819
00820
00821 if(alpm_pkg_has_scriptlet(newpkg)
00822 && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
00823 if(is_upgrade) {
00824 _alpm_runscriptlet(handle->root, scriptlet, "post_upgrade",
00825 alpm_pkg_get_version(newpkg),
00826 oldpkg ? alpm_pkg_get_version(oldpkg) : NULL, trans);
00827 } else {
00828 _alpm_runscriptlet(handle->root, scriptlet, "post_install",
00829 alpm_pkg_get_version(newpkg), NULL, trans);
00830 }
00831 }
00832
00833 if(is_upgrade) {
00834 EVENT(trans, PM_TRANS_EVT_UPGRADE_DONE, newpkg, oldpkg);
00835 } else {
00836 EVENT(trans, PM_TRANS_EVT_ADD_DONE, newpkg, oldpkg);
00837 }
00838
00839 _alpm_pkg_free(oldpkg);
00840
00841 return(0);
00842 }
00843
00844 int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
00845 {
00846 int pkg_count, pkg_current;
00847 alpm_list_t *targ;
00848
00849 ALPM_LOG_FUNC;
00850
00851 ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
00852 ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
00853
00854 if(trans->packages == NULL) {
00855 return(0);
00856 }
00857
00858 pkg_count = alpm_list_count(trans->targets);
00859 pkg_current = 1;
00860
00861
00862 for(targ = trans->packages; targ; targ = targ->next) {
00863 if(handle->trans->state == STATE_INTERRUPTED) {
00864 return(0);
00865 }
00866
00867 pmpkg_t *newpkg = (pmpkg_t *)targ->data;
00868 commit_single_pkg(newpkg, pkg_current, pkg_count, trans, db);
00869 pkg_current++;
00870 }
00871
00872
00873 _alpm_log(PM_LOG_DEBUG, "running \"ldconfig -r %s\"\n", handle->root);
00874 _alpm_ldconfig(handle->root);
00875
00876 return(0);
00877 }
00878
00879