00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include <fcntl.h>
00028 #include <string.h>
00029 #include <unistd.h>
00030 #include <time.h>
00031 #include <dirent.h>
00032
00033
00034 #include "sync.h"
00035 #include "alpm_list.h"
00036 #include "log.h"
00037 #include "error.h"
00038 #include "package.h"
00039 #include "db.h"
00040 #include "cache.h"
00041 #include "deps.h"
00042 #include "conflict.h"
00043 #include "trans.h"
00044 #include "util.h"
00045 #include "handle.h"
00046 #include "alpm.h"
00047 #include "server.h"
00048 #include "delta.h"
00049
00050 pmsyncpkg_t *_alpm_sync_new(int type, pmpkg_t *spkg, void *data)
00051 {
00052 pmsyncpkg_t *sync;
00053
00054 ALPM_LOG_FUNC;
00055
00056 CALLOC(sync, 1, sizeof(pmsyncpkg_t), RET_ERR(PM_ERR_MEMORY, NULL));
00057
00058 sync->type = type;
00059 sync->pkg = spkg;
00060 sync->data = data;
00061
00062 return(sync);
00063 }
00064
00065 void _alpm_sync_free(pmsyncpkg_t *sync)
00066 {
00067 ALPM_LOG_FUNC;
00068
00069 if(sync == NULL) {
00070 return;
00071 }
00072
00073
00074 if(sync->type == PM_SYNC_TYPE_REPLACE) {
00075 alpm_list_free(sync->data);
00076 }
00077 sync->data = NULL;
00078 FREE(sync);
00079 }
00080
00081 static void synclist_free(alpm_list_t *syncpkgs)
00082 {
00083 if(syncpkgs) {
00084 alpm_list_t *tmp;
00085 for(tmp = syncpkgs; tmp; tmp = alpm_list_next(tmp)) {
00086 if(tmp->data) {
00087 _alpm_sync_free(tmp->data);
00088 }
00089 }
00090 alpm_list_free(syncpkgs);
00091 }
00092
00093 }
00094
00095
00096
00097 static int find_replacements(pmtrans_t *trans, pmdb_t *db_local,
00098 alpm_list_t *dbs_sync, alpm_list_t **syncpkgs)
00099 {
00100 alpm_list_t *i, *j, *k;
00101
00102 ALPM_LOG_FUNC;
00103
00104 if(syncpkgs == NULL) {
00105 return(-1);
00106 }
00107
00108
00109 _alpm_log(PM_LOG_DEBUG, "checking for package replacements\n");
00110 for(i = dbs_sync; i; i = i->next) {
00111 pmdb_t *db = i->data;
00112
00113
00114 for(j = _alpm_db_get_pkgcache(db); j; j = j->next) {
00115 pmpkg_t *spkg = j->data;
00116
00117 for(k = alpm_pkg_get_replaces(spkg); k; k = k->next) {
00118 const char *replacement = k->data;
00119
00120 pmpkg_t *lpkg = _alpm_db_get_pkgfromcache(db_local, replacement);
00121 if(!lpkg) {
00122 continue;
00123 }
00124
00125 _alpm_log(PM_LOG_DEBUG, "checking replacement '%s' for package '%s'\n",
00126 replacement, spkg->name);
00127
00128 if(_alpm_pkg_should_ignore(spkg) || _alpm_pkg_should_ignore(lpkg)) {
00129 _alpm_log(PM_LOG_WARNING, _("%s-%s: ignoring package upgrade (to be replaced by %s-%s)\n"),
00130 alpm_pkg_get_name(lpkg), alpm_pkg_get_version(lpkg),
00131 alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg));
00132 } else {
00133
00134 if(trans) {
00135 int doreplace = 0;
00136 QUESTION(trans, PM_TRANS_CONV_REPLACE_PKG, lpkg, spkg, db->treename, &doreplace);
00137 if(!doreplace) {
00138 continue;
00139 }
00140 }
00141
00142
00143
00144
00145 pmsyncpkg_t *sync;
00146
00147
00148 sync = _alpm_sync_find(*syncpkgs, alpm_pkg_get_name(spkg));
00149 if(sync) {
00150
00151 sync->data = alpm_list_add(sync->data, lpkg);
00152 } else {
00153
00154 sync = _alpm_sync_new(PM_SYNC_TYPE_REPLACE, spkg, NULL);
00155 if(sync == NULL) {
00156 pm_errno = PM_ERR_MEMORY;
00157 synclist_free(*syncpkgs);
00158 return(-1);
00159 }
00160 sync->data = alpm_list_add(NULL, lpkg);
00161 *syncpkgs = alpm_list_add(*syncpkgs, sync);
00162 }
00163 _alpm_log(PM_LOG_DEBUG, "%s-%s elected for upgrade (to be replaced by %s-%s)\n",
00164 alpm_pkg_get_name(lpkg), alpm_pkg_get_version(lpkg),
00165 alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg));
00166 }
00167 }
00168 }
00169 }
00170 return(0);
00171 }
00172
00173
00174
00175
00176
00177 int SYMEXPORT alpm_sync_sysupgrade(pmdb_t *db_local,
00178 alpm_list_t *dbs_sync, alpm_list_t **syncpkgs)
00179 {
00180 return(_alpm_sync_sysupgrade(NULL, db_local, dbs_sync, syncpkgs));
00181 }
00182
00183 int _alpm_sync_sysupgrade(pmtrans_t *trans,
00184 pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **syncpkgs)
00185 {
00186 alpm_list_t *i, *j;
00187
00188 ALPM_LOG_FUNC;
00189
00190 if(syncpkgs == NULL) {
00191 return(-1);
00192 }
00193
00194 if(find_replacements(trans, db_local, dbs_sync, syncpkgs)) {
00195 return(-1);
00196 }
00197
00198
00199 _alpm_log(PM_LOG_DEBUG, "checking for package upgrades\n");
00200 for(i = _alpm_db_get_pkgcache(db_local); i; i = i->next) {
00201 int replace = 0;
00202 pmpkg_t *local = i->data;
00203 pmpkg_t *spkg = NULL;
00204 pmsyncpkg_t *sync;
00205
00206 for(j = dbs_sync; !spkg && j; j = j->next) {
00207 spkg = _alpm_db_get_pkgfromcache(j->data, alpm_pkg_get_name(local));
00208 }
00209 if(spkg == NULL) {
00210 _alpm_log(PM_LOG_DEBUG, "'%s' not found in sync db -- skipping\n",
00211 alpm_pkg_get_name(local));
00212 continue;
00213 }
00214
00215
00216 for(j = *syncpkgs; j && !replace; j=j->next) {
00217 sync = j->data;
00218 if(sync->type == PM_SYNC_TYPE_REPLACE) {
00219 if(_alpm_pkg_find(alpm_pkg_get_name(spkg), sync->data)) {
00220 replace = 1;
00221 }
00222 }
00223 }
00224 if(replace) {
00225 _alpm_log(PM_LOG_DEBUG, "'%s' is already elected for removal -- skipping\n",
00226 alpm_pkg_get_name(local));
00227 continue;
00228 }
00229
00230
00231 if(_alpm_pkg_compare_versions(local, spkg)) {
00232 _alpm_log(PM_LOG_DEBUG, "%s elected for upgrade (%s => %s)\n",
00233 alpm_pkg_get_name(local), alpm_pkg_get_version(local),
00234 alpm_pkg_get_version(spkg));
00235 if(!_alpm_sync_find(*syncpkgs, alpm_pkg_get_name(spkg))) {
00236
00237 if(_alpm_pkg_should_ignore(spkg)) {
00238 _alpm_log(PM_LOG_WARNING, _("%s: ignoring package upgrade (%s => %s)\n"),
00239 alpm_pkg_get_name(local), alpm_pkg_get_version(local),
00240 alpm_pkg_get_version(spkg));
00241 continue;
00242 }
00243
00244 sync = _alpm_sync_new(PM_SYNC_TYPE_UPGRADE, spkg, local);
00245 if(sync == NULL) {
00246 pm_errno = PM_ERR_MEMORY;
00247 synclist_free(*syncpkgs);
00248 return(-1);
00249 }
00250 *syncpkgs = alpm_list_add(*syncpkgs, sync);
00251 }
00252 }
00253 }
00254
00255 return(0);
00256 }
00257
00258 int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, char *name)
00259 {
00260 char *targline;
00261 char *targ;
00262 alpm_list_t *j;
00263 pmpkg_t *local;
00264 pmpkg_t *spkg = NULL;
00265 pmsyncpkg_t *sync;
00266 int repo_found = 0;
00267
00268 ALPM_LOG_FUNC;
00269
00270 ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
00271 ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
00272 ASSERT(name != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
00273 STRDUP(targline, name, RET_ERR(PM_ERR_MEMORY, -1));
00274
00275 targ = strchr(targline, '/');
00276 if(targ) {
00277
00278 *targ = '\0';
00279 targ++;
00280 _alpm_log(PM_LOG_DEBUG, "searching for target '%s' in repo\n", targ);
00281 for(j = dbs_sync; j && !spkg; j = j->next) {
00282 pmdb_t *db = j->data;
00283 if(strcmp(db->treename, targline) == 0) {
00284 repo_found = 1;
00285 spkg = _alpm_db_get_pkgfromcache(db, targ);
00286 if(spkg == NULL) {
00287 pm_errno = PM_ERR_PKG_NOT_FOUND;
00288 goto error;
00289 }
00290 }
00291 }
00292 if(!repo_found) {
00293 _alpm_log(PM_LOG_ERROR, _("repository '%s' not found\n"), targline);
00294 pm_errno = PM_ERR_PKG_REPO_NOT_FOUND;
00295 goto error;
00296 }
00297 } else {
00298 targ = targline;
00299 for(j = dbs_sync; j && !spkg; j = j->next) {
00300 pmdb_t *db = j->data;
00301 spkg = _alpm_db_get_pkgfromcache(db, targ);
00302 }
00303 if(spkg == NULL) {
00304 pm_errno = PM_ERR_PKG_NOT_FOUND;
00305 goto error;
00306 }
00307 }
00308
00309 if(_alpm_pkg_should_ignore(spkg)) {
00310 int resp;
00311 QUESTION(trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, spkg, NULL, NULL, &resp);
00312 if (!resp) {
00313 return(0);
00314 }
00315 }
00316
00317 local = _alpm_db_get_pkgfromcache(db_local, alpm_pkg_get_name(spkg));
00318 if(local) {
00319 if(_alpm_pkg_compare_versions(local, spkg) == 0) {
00320
00321 if(trans->flags & PM_TRANS_FLAG_NEEDED) {
00322 _alpm_log(PM_LOG_WARNING, _("%s-%s is up to date -- skipping\n"),
00323 alpm_pkg_get_name(local), alpm_pkg_get_version(local));
00324 return(0);
00325 } else {
00326 _alpm_log(PM_LOG_WARNING, _("%s-%s is up to date -- reinstalling\n"),
00327 alpm_pkg_get_name(local), alpm_pkg_get_version(local));
00328 }
00329 }
00330 }
00331
00332
00333 if(!_alpm_sync_find(trans->packages, alpm_pkg_get_name(spkg))) {
00334 sync = _alpm_sync_new(PM_SYNC_TYPE_UPGRADE, spkg, local);
00335 if(sync == NULL) {
00336 pm_errno = PM_ERR_MEMORY;
00337 goto error;
00338 }
00339 _alpm_log(PM_LOG_DEBUG, "adding target '%s' to the transaction set\n",
00340 alpm_pkg_get_name(spkg));
00341 trans->packages = alpm_list_add(trans->packages, sync);
00342 }
00343
00344 FREE(targline);
00345 return(0);
00346
00347 error:
00348 if(targline) {
00349 FREE(targline);
00350 }
00351 return(-1);
00352 }
00353
00354
00355
00356 static int syncpkg_cmp(const void *s1, const void *s2)
00357 {
00358 const pmsyncpkg_t *sp1 = s1;
00359 const pmsyncpkg_t *sp2 = s2;
00360 pmpkg_t *p1, *p2;
00361
00362 p1 = alpm_sync_get_pkg(sp1);
00363 p2 = alpm_sync_get_pkg(sp2);
00364
00365 return(strcmp(alpm_pkg_get_name(p1), alpm_pkg_get_name(p2)));
00366 }
00367
00368 int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **data)
00369 {
00370 alpm_list_t *deps = NULL;
00371 alpm_list_t *list = NULL, *remove = NULL;
00372 alpm_list_t *i, *j;
00373 int ret = 0;
00374
00375 ALPM_LOG_FUNC;
00376
00377 ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
00378 ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
00379
00380 if(data) {
00381 *data = NULL;
00382 }
00383
00384 if(!(trans->flags & PM_TRANS_FLAG_DEPENDSONLY)) {
00385 for(i = trans->packages; i; i = i->next) {
00386 pmsyncpkg_t *sync = i->data;
00387 list = alpm_list_add(list, sync->pkg);
00388 }
00389 }
00390
00391 if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
00392
00393 EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL);
00394 _alpm_log(PM_LOG_DEBUG, "resolving target's dependencies\n");
00395
00396
00397 for(i = trans->packages; i; i = i->next) {
00398 pmsyncpkg_t *sync = i->data;
00399 if(sync->type == PM_SYNC_TYPE_REPLACE) {
00400 for(j = sync->data; j; j = j->next) {
00401 remove = alpm_list_add(remove, j->data);
00402 }
00403 }
00404 }
00405
00406 for(i = trans->packages; i; i = i->next) {
00407 pmpkg_t *spkg = ((pmsyncpkg_t *)i->data)->pkg;
00408 if(_alpm_resolvedeps(db_local, dbs_sync, spkg, &list,
00409 remove, trans, data) == -1) {
00410
00411 ret = -1;
00412 goto cleanup;
00413 }
00414 }
00415
00416 if((trans->flags & PM_TRANS_FLAG_DEPENDSONLY)) {
00417 FREELIST(trans->packages);
00418 }
00419
00420 for(i = list; i; i = i->next) {
00421
00422 pmpkg_t *spkg = i->data;
00423 if(!_alpm_sync_find(trans->packages, alpm_pkg_get_name(spkg))) {
00424 pmsyncpkg_t *sync = _alpm_sync_new(PM_SYNC_TYPE_DEPEND, spkg, NULL);
00425 if(sync == NULL) {
00426 ret = -1;
00427 goto cleanup;
00428 }
00429 trans->packages = alpm_list_add(trans->packages, sync);
00430 _alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",
00431 alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg));
00432 }
00433 }
00434
00435
00436 alpm_list_t *sortlist = _alpm_sortbydeps(list, PM_TRANS_TYPE_ADD);
00437 alpm_list_t *newpkgs = NULL;
00438 for(i = sortlist; i; i = i->next) {
00439 for(j = trans->packages; j; j = j->next) {
00440 pmsyncpkg_t *s = j->data;
00441 if(s->pkg == i->data) {
00442 newpkgs = alpm_list_add(newpkgs, s);
00443 }
00444 }
00445 }
00446 alpm_list_free(sortlist);
00447 alpm_list_free(trans->packages);
00448 trans->packages = newpkgs;
00449
00450 EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_DONE, NULL, NULL);
00451 }
00452
00453
00454 if(!(trans->flags & (PM_TRANS_FLAG_NOCONFLICTS | PM_TRANS_FLAG_PRINTURIS))) {
00455
00456 EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_START, NULL, NULL);
00457
00458 _alpm_log(PM_LOG_DEBUG, "looking for conflicts\n");
00459 deps = _alpm_checkconflicts(db_local, list);
00460 if(deps) {
00461 int errorout = 0;
00462 alpm_list_t *asked = NULL;
00463 pmconflict_t *conflict = NULL;
00464
00465 for(i = deps; i && !errorout; i = i->next) {
00466 pmsyncpkg_t *sync;
00467 pmpkg_t *found = NULL;
00468
00469 conflict = i->data;
00470 _alpm_log(PM_LOG_DEBUG, "package '%s' conflicts with '%s'\n",
00471 conflict->package1, conflict->package2);
00472
00473
00474 for(j = trans->packages; j && !found; j = j->next) {
00475 sync = j->data;
00476 if(sync->type == PM_SYNC_TYPE_REPLACE) {
00477 found = _alpm_pkg_find(conflict->package2, sync->data);
00478 }
00479 }
00480 if(found) {
00481 _alpm_log(PM_LOG_DEBUG, "'%s' is already elected for removal -- skipping\n",
00482 alpm_pkg_get_name(found));
00483 continue;
00484 }
00485
00486 sync = _alpm_sync_find(trans->packages, conflict->package1);
00487 if(sync == NULL) {
00488 _alpm_log(PM_LOG_DEBUG, "'%s' not found in transaction set -- skipping\n",
00489 conflict->package1);
00490 continue;
00491 }
00492 pmpkg_t *local = _alpm_db_get_pkgfromcache(db_local, conflict->package2);
00493
00494 if(alpm_list_find(alpm_pkg_get_provides(sync->pkg),
00495 conflict->package2, _alpm_prov_cmp)) {
00496
00497
00498 _alpm_log(PM_LOG_DEBUG, "package '%s' provides its own conflict\n",
00499 conflict->package1);
00500 if(!local) {
00501 char *rmpkg = NULL;
00502 void *target, *depend;
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 target = alpm_list_find_str(trans->targets, conflict->package1);
00517 depend = alpm_list_find_str(trans->targets, conflict->package2);
00518 if(depend && !target) {
00519 _alpm_log(PM_LOG_DEBUG, "'%s' is in the target list -- keeping it\n",
00520 conflict->package2);
00521
00522 rmpkg = conflict->package1;
00523 } else if(target && !depend) {
00524 _alpm_log(PM_LOG_DEBUG, "'%s' is in the target list -- keeping it\n",
00525 conflict->package1);
00526
00527 rmpkg = conflict->package2;
00528 } else {
00529
00530
00531 rmpkg = conflict->package2;
00532 }
00533 if(rmpkg) {
00534 pmsyncpkg_t *rsync = _alpm_sync_find(trans->packages, rmpkg);
00535 if(rsync) {
00536 void *vpkg;
00537 _alpm_log(PM_LOG_DEBUG, "removing '%s' from target list\n",
00538 rsync->pkg->name);
00539 trans->packages = alpm_list_remove(trans->packages, rsync,
00540 syncpkg_cmp, &vpkg);
00541 _alpm_sync_free(vpkg);
00542 }
00543 continue;
00544 }
00545 }
00546 }
00547
00548 _alpm_log(PM_LOG_DEBUG, "resolving package '%s' conflict\n",
00549 conflict->package1);
00550 if(local) {
00551 int doremove = 0;
00552 if(!alpm_list_find_str(asked, conflict->package2)) {
00553 QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, conflict->package1,
00554 conflict->package2, NULL, &doremove);
00555 asked = alpm_list_add(asked, strdup(conflict->package2));
00556 if(doremove) {
00557 if(sync->type != PM_SYNC_TYPE_REPLACE) {
00558
00559 sync->type = PM_SYNC_TYPE_REPLACE;
00560 sync->data = NULL;
00561 }
00562
00563 _alpm_log(PM_LOG_DEBUG, "electing '%s' for removal\n",
00564 conflict->package2);
00565 sync->data = alpm_list_add(sync->data, local);
00566
00567 pmsyncpkg_t *rsync = _alpm_sync_find(trans->packages,
00568 conflict->package2);
00569 if(rsync) {
00570
00571 void *vpkg;
00572 _alpm_log(PM_LOG_DEBUG, "removing '%s' from target list\n",
00573 conflict->package2);
00574 trans->packages = alpm_list_remove(trans->packages, rsync,
00575 syncpkg_cmp, &vpkg);
00576 _alpm_sync_free(vpkg);
00577 }
00578 } else {
00579
00580 _alpm_log(PM_LOG_ERROR, _("unresolvable package conflicts detected\n"));
00581 errorout = 1;
00582 }
00583 }
00584 } else {
00585 _alpm_log(PM_LOG_ERROR, _("unresolvable package conflicts detected\n"));
00586 errorout = 1;
00587 }
00588 }
00589 if(errorout) {
00590
00591 pm_errno = PM_ERR_CONFLICTING_DEPS;
00592 if(data) {
00593 pmconflict_t *lastconflict = conflict;
00594 if((conflict = malloc(sizeof(pmconflict_t))) == NULL) {
00595 _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %zd bytes\n"),
00596 sizeof(pmconflict_t));
00597 FREELIST(*data);
00598 pm_errno = PM_ERR_MEMORY;
00599 } else {
00600 *conflict = *lastconflict;
00601 *data = alpm_list_add(*data, conflict);
00602 }
00603 }
00604 FREELIST(asked);
00605 alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_conflict_free);
00606 alpm_list_free(deps);
00607 ret = -1;
00608 goto cleanup;
00609 }
00610 FREELIST(asked);
00611 FREELIST(deps);
00612 }
00613 EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_DONE, NULL, NULL);
00614 }
00615
00616 if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
00617
00618 alpm_list_free(list);
00619 list = NULL;
00620 for(i = trans->packages; i; i = i->next) {
00621 pmsyncpkg_t *sync = i->data;
00622 list = alpm_list_add(list, sync->pkg);
00623 }
00624 alpm_list_free(remove);
00625 remove = NULL;
00626 for(i = trans->packages; i; i = i->next) {
00627 pmsyncpkg_t *sync = i->data;
00628 if(sync->type == PM_SYNC_TYPE_REPLACE) {
00629 for(j = sync->data; j; j = j->next) {
00630 remove = alpm_list_add(remove, j->data);
00631 }
00632 }
00633 }
00634
00635 _alpm_log(PM_LOG_DEBUG, "checking dependencies\n");
00636 deps = alpm_checkdeps(db_local, 1, remove, list);
00637 if(deps) {
00638 pm_errno = PM_ERR_UNSATISFIED_DEPS;
00639 ret = -1;
00640 if(data) {
00641 *data = deps;
00642 } else {
00643 FREELIST(deps);
00644 }
00645 goto cleanup;
00646 }
00647 }
00648
00649 cleanup:
00650 alpm_list_free(list);
00651 alpm_list_free(remove);
00652
00653 return(ret);
00654 }
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 static alpm_list_t *pkg_upgrade_delta_path(pmpkg_t *newpkg, pmdb_t *db_local)
00671 {
00672 pmpkg_t *oldpkg = alpm_db_get_pkg(db_local, newpkg->name);
00673 alpm_list_t *ret = NULL;
00674
00675 if(oldpkg) {
00676 const char *oldname = alpm_pkg_get_filename(oldpkg);
00677 char *oldpath = _alpm_filecache_find(oldname);
00678
00679 if(oldpath) {
00680 alpm_list_t *deltas = _alpm_shortest_delta_path(
00681 alpm_pkg_get_deltas(newpkg),
00682 alpm_pkg_get_version(oldpkg),
00683 alpm_pkg_get_version(newpkg));
00684
00685 if(deltas) {
00686 unsigned long dltsize = _alpm_delta_path_size(deltas);
00687 unsigned long pkgsize = alpm_pkg_get_size(newpkg);
00688
00689 if(dltsize < pkgsize * MAX_DELTA_RATIO) {
00690 ret = deltas;
00691 } else {
00692 ret = NULL;
00693 alpm_list_free(deltas);
00694 }
00695 }
00696
00697 FREE(oldpath);
00698 }
00699 }
00700
00701 return(ret);
00702 }
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 unsigned long SYMEXPORT alpm_pkg_download_size(pmpkg_t *newpkg, pmdb_t *db_local)
00713 {
00714 char *fpath = _alpm_filecache_find(alpm_pkg_get_filename(newpkg));
00715 unsigned long size = 0;
00716
00717 if(fpath) {
00718 size = 0;
00719 } else if(handle->usedelta) {
00720 alpm_list_t *deltas = pkg_upgrade_delta_path(newpkg, db_local);
00721
00722 if(deltas) {
00723 size = _alpm_delta_path_size_uncached(deltas);
00724 } else {
00725 size = alpm_pkg_get_size(newpkg);
00726 }
00727
00728 alpm_list_free(deltas);
00729 } else {
00730 size = alpm_pkg_get_size(newpkg);
00731 }
00732
00733 FREE(fpath);
00734
00735 return(size);
00736 }
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750 static int apply_deltas(pmtrans_t *trans, alpm_list_t *patches)
00751 {
00752
00753
00754 pmpkg_t *lastpkg = NULL;
00755 int lastpkg_failed = 0;
00756 int ret = 0;
00757 const char *cachedir = _alpm_filecache_setup();
00758
00759 alpm_list_t *p = patches;
00760 while(p) {
00761 pmpkg_t *pkg;
00762 pmdelta_t *d;
00763 char command[PATH_MAX], fname[PATH_MAX];
00764 char pkgfilename[PATH_MAX];
00765
00766 pkg = alpm_list_getdata(p);
00767 p = alpm_list_next(p);
00768
00769 d = alpm_list_getdata(p);
00770 p = alpm_list_next(p);
00771
00772
00773 if(lastpkg_failed) {
00774 if(pkg == lastpkg) {
00775 continue;
00776 } else {
00777 lastpkg_failed = 0;
00778 }
00779 }
00780
00781
00782
00783
00784
00785
00786
00787
00788 snprintf(command, PATH_MAX,
00789 "xdelta patch"
00790 " %s/%s"
00791 " %s/%s-%s-%s" PKGEXT
00792 " %s/%s-%s-%s" PKGEXT,
00793 cachedir, d->filename,
00794 cachedir, pkg->name, d->from, pkg->arch,
00795 cachedir, pkg->name, d->to, pkg->arch);
00796
00797 _alpm_log(PM_LOG_DEBUG, _("command: %s\n"), command);
00798
00799 snprintf(pkgfilename, PATH_MAX, "%s-%s-%s" PKGEXT,
00800 pkg->name, d->to, pkg->arch);
00801
00802 EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_START, pkgfilename, d->filename);
00803
00804 if(system(command) == 0) {
00805 EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_DONE, NULL, NULL);
00806
00807
00808 snprintf(fname, PATH_MAX, "%s/%s", cachedir, d->filename);
00809 unlink(fname);
00810
00811
00812
00813
00814
00815 if(pkg == lastpkg) {
00816 snprintf(fname, PATH_MAX, "%s/%s-%s-%s" PKGEXT,
00817 cachedir, pkg->name, d->from, pkg->arch);
00818 unlink(fname);
00819 } else {
00820 lastpkg = pkg;
00821 }
00822 } else {
00823 EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_FAILED, NULL, NULL);
00824 lastpkg_failed = 1;
00825 ret = 1;
00826 }
00827 }
00828
00829 return(ret);
00830 }
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844 static int test_md5sum(pmtrans_t *trans, const char *filename,
00845 const char *md5sum, alpm_list_t **data)
00846 {
00847 char *filepath;
00848 char *md5sum2;
00849 char *errormsg = NULL;
00850 int ret = 0;
00851
00852 filepath = _alpm_filecache_find(filename);
00853 md5sum2 = alpm_get_md5sum(filepath);
00854
00855 if(md5sum == NULL) {
00856 if(data) {
00857
00858 if((errormsg = calloc(512, sizeof(char))) == NULL) {
00859 RET_ERR(PM_ERR_MEMORY, -1);
00860 }
00861 snprintf(errormsg, 512, _("can't get md5 checksum for file %s\n"),
00862 filename);
00863 *data = alpm_list_add(*data, errormsg);
00864 }
00865 ret = 1;
00866 } else if(md5sum2 == NULL) {
00867 if(data) {
00868 if((errormsg = calloc(512, sizeof(char))) == NULL) {
00869 RET_ERR(PM_ERR_MEMORY, -1);
00870 }
00871 snprintf(errormsg, 512, _("can't get md5 checksum for file %s\n"),
00872 filename);
00873 *data = alpm_list_add(*data, errormsg);
00874 }
00875 ret = 1;
00876 } else if(strcmp(md5sum, md5sum2) != 0) {
00877 int doremove = 0;
00878 QUESTION(trans, PM_TRANS_CONV_CORRUPTED_PKG, (char *)filename,
00879 NULL, NULL, &doremove);
00880 if(doremove) {
00881 unlink(filepath);
00882 }
00883 if(data) {
00884 if((errormsg = calloc(512, sizeof(char))) == NULL) {
00885 RET_ERR(PM_ERR_MEMORY, -1);
00886 }
00887 snprintf(errormsg, 512, _("file %s was corrupted (bad MD5 checksum)\n"),
00888 filename);
00889 *data = alpm_list_add(*data, errormsg);
00890 }
00891 ret = 1;
00892 }
00893
00894 FREE(filepath);
00895 FREE(md5sum2);
00896
00897 return(ret);
00898 }
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908 static int test_delta_md5sum(pmtrans_t *trans, pmdelta_t *delta,
00909 alpm_list_t **data)
00910 {
00911 const char *filename;
00912 const char *md5sum;
00913 int ret = 0;
00914
00915 filename = alpm_delta_get_filename(delta);
00916 md5sum = alpm_delta_get_md5sum(delta);
00917
00918 ret = test_md5sum(trans, filename, md5sum, data);
00919
00920 return(ret);
00921 }
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 static int test_pkg_md5sum(pmtrans_t *trans, pmpkg_t *pkg, alpm_list_t **data)
00932 {
00933 const char *filename;
00934 const char *md5sum;
00935 int ret = 0;
00936
00937 filename = alpm_pkg_get_filename(pkg);
00938 md5sum = alpm_pkg_get_md5sum(pkg);
00939
00940 ret = test_md5sum(trans, filename, md5sum, data);
00941
00942 return(ret);
00943 }
00944
00945 int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
00946 {
00947 alpm_list_t *i, *j, *files = NULL;
00948 alpm_list_t *patches = NULL, *deltas = NULL;
00949 pmtrans_t *tr = NULL;
00950 int replaces = 0, retval = 0;
00951 const char *cachedir = NULL;
00952 int dltotal = 0, dl = 0;
00953
00954 ALPM_LOG_FUNC;
00955
00956 ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
00957 ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
00958
00959 cachedir = _alpm_filecache_setup();
00960 trans->state = STATE_DOWNLOADING;
00961
00962
00963
00964 for(j = trans->packages; j; j = j->next) {
00965 pmsyncpkg_t *sync = j->data;
00966 pmpkg_t *spkg = sync->pkg;
00967 dltotal += alpm_pkg_download_size(spkg, db_local);
00968 }
00969
00970
00971 for(i = handle->