From d05f0047a02a2b3b3f1a07c0feb980837a3496a3 Mon Sep 17 00:00:00 2001 From: Judd Vinet Date: Fri, 10 Jun 2005 21:31:25 +0000 Subject: Imported from pacman-2.9.6.tar.gz --- src/pacman.c | 158 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 103 insertions(+), 55 deletions(-) (limited to 'src/pacman.c') diff --git a/src/pacman.c b/src/pacman.c index f12643e5..3daa1fe4 100644 --- a/src/pacman.c +++ b/src/pacman.c @@ -240,7 +240,7 @@ int main(int argc, char *argv[]) /* start the requested operation */ switch(pmo_op) { case PM_ADD: ret = pacman_add(db_local, pm_targets, NULL); break; - case PM_REMOVE: ret = pacman_remove(db_local, pm_targets); break; + case PM_REMOVE: ret = pacman_remove(db_local, pm_targets, NULL); break; case PM_UPGRADE: ret = pacman_upgrade(db_local, pm_targets, NULL); break; case PM_QUERY: ret = pacman_query(db_local, pm_targets); break; case PM_SYNC: ret = pacman_sync(db_local, pm_targets); break; @@ -1323,7 +1323,7 @@ int pacman_sync(pacdb_t *db, PMList *targets) int oldval = pmo_nodeps; /* we make pacman_remove() skip dependency checks by setting pmo_nodeps high */ pmo_nodeps = 1; - retcode = pacman_remove(db, rmtargs); + retcode = pacman_remove(db, rmtargs, NULL); pmo_nodeps = oldval; FREELIST(rmtargs); if(retcode == 1) { @@ -1356,7 +1356,7 @@ int pacman_sync(pacdb_t *db, PMList *targets) int oldval = pmo_nodeps; /* we make pacman_remove() skip dependency checks by setting pmo_nodeps high */ pmo_nodeps = 1; - allgood = !pacman_remove(db, rmtargs); + allgood = !pacman_remove(db, rmtargs, NULL); pmo_nodeps = oldval; if(!allgood) { fprintf(stderr, "package removal failed. aborting...\n"); @@ -1367,11 +1367,17 @@ int pacman_sync(pacdb_t *db, PMList *targets) allgood = !pacman_upgrade(db, files, dependonly); } /* propagate replaced packages' requiredby fields to their new owners */ + /* XXX: segfault */ if(allgood) { for(i = final; i; i = i->next) { syncpkg_t *sync = (syncpkg_t*)i->data; if(sync->replaces) { - pkginfo_t *new = db_scan(db, sync->pkg->name, INFRQ_DEPENDS); + pkginfo_t *new; + new = db_scan(db, sync->pkg->name, INFRQ_DEPENDS); + if(!new) { + fprintf(stderr, "Something has gone terribly wrong. I'll probably segfault now.\n"); + fflush(stderr); + } for(j = sync->replaces; j; j = j->next) { pkginfo_t *old = (pkginfo_t*)j->data; /* merge lists */ @@ -1448,6 +1454,8 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly) struct stat buf; PMList *targ, *lp, *j, *k; PMList *alltargs = NULL; + PMList *skiplist = NULL; + unsigned short real_pmo_upgrade; tartype_t gztype = { (openfunc_t) gzopen_frontend, @@ -1646,7 +1654,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly) alltargs = k; /* make sure pacman_remove does it's own dependency check */ pmo_upgrade = 0; - retcode = pacman_remove(db, rmtargs); + retcode = pacman_remove(db, rmtargs, NULL); list_free(rmtargs); if(retcode == 1) { fprintf(stderr, "\n%s aborted.\n", oldupg ? "upgrade" : "install"); @@ -1683,7 +1691,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly) if(!pmo_force) { printf("checking for file conflicts... "); fflush(stdout); - lp = db_find_conflicts(db, alltargs, pmo_root); + lp = db_find_conflicts(db, alltargs, pmo_root, &skiplist); if(lp) { printf("\nerror: the following file conflicts were found:\n"); for(j = lp; j; j = j->next) { @@ -1738,7 +1746,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly) /* copy over the install reason */ info->reason = oldpkg->reason; vprint("removing old package first...\n"); - retcode = pacman_remove(db, tmp); + retcode = pacman_remove(db, tmp, skiplist); FREELIST(tmp); if(retcode == 1) { fprintf(stderr, "\nupgrade aborted.\n"); @@ -1793,7 +1801,20 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly) snprintf(expath, PATH_MAX, "%s%s", pmo_root, pathname); } - if(!stat(expath, &buf) && !S_ISDIR(buf.st_mode)) { + /* if a file is in NoUpgrade and missing from the filesystem, + * then we never extract it. + * + * eg, /home/httpd/html/index.html may be removed so index.php + * could be used + */ + if(stat(expath, &buf) && is_in(pathname, pmo_noupgrade)) { + vprint("%s is in NoUpgrade - skipping\n", pathname); + logaction(stderr, "warning: %s is in NoUpgrade -- skipping extraction", pathname); + tar_skip_regfile(tar); + continue; + } + + if(!notouch && !stat(expath, &buf) && !S_ISDIR(buf.st_mode)) { /* file already exists */ if(is_in(pathname, pmo_noupgrade)) { notouch = 1; @@ -1916,7 +1937,6 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly) vprint("%s is in NoUpgrade - skipping\n", pathname); strncat(expath, ".pacnew", PATH_MAX); logaction(stderr, "warning: extracting %s%s as %s", pmo_root, pathname, expath); - /*tar_skip_regfile(tar);*/ } if(pmo_force) { /* if pmo_force was used, then unlink() each file (whether it's there @@ -1980,6 +2000,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly) continue; } } + FREEPKG(tmpp); } vprint("Updating database..."); @@ -2019,6 +2040,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly) if(provides) { /* use the first one */ depinfo = db_scan(db, provides->data, INFRQ_DEPENDS); + FREELIST(provides); if(depinfo == NULL) { /* wtf */ continue; @@ -2066,7 +2088,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly) return(ret); } -int pacman_remove(pacdb_t *db, PMList *targets) +int pacman_remove(pacdb_t *db, PMList *targets, PMList *skiplist) { char line[PATH_MAX+1]; char pm_install[PATH_MAX+1]; @@ -2137,8 +2159,17 @@ int pacman_remove(pacdb_t *db, PMList *targets) for(j = lp; j; j = j->next) { depmissing_t* miss = (depmissing_t*)j->data; info = db_scan(db, miss->depend.name, INFRQ_ALL); + if(info == NULL) { + fprintf(stderr, "error: %s is not installed, even though it is required\n", miss->depend.name); + fprintf(stderr, " by an installed package (%s)\n\n", miss->target); + fprintf(stderr, "cannot complete a cascade removal with a broken dependency chain\n"); + FREELISTPKGS(alltargs); + return(1); + } if(!is_pkgin(info, alltargs)) { alltargs = list_add(alltargs, info); + } else { + FREEPKG(info); } } list_free(lp); @@ -2198,16 +2229,19 @@ int pacman_remove(pacdb_t *db, PMList *targets) /* iterate through the list backwards, unlinking files */ for(lp = list_last(info->files); lp; lp = lp->prev) { int nb = 0; - if(needbackup((char*)lp->data, info->backup)) { + char *file; + + file = (char*)lp->data; + if(needbackup(file, info->backup)) { nb = 1; } if(!nb && pmo_upgrade) { /* check pmo_noupgrade */ - if(is_in((char*)lp->data, pmo_noupgrade)) { + if(is_in(file, pmo_noupgrade)) { nb = 1; } } - snprintf(line, PATH_MAX, "%s%s", pmo_root, (char*)lp->data); + snprintf(line, PATH_MAX, "%s%s", pmo_root, file); if(lstat(line, &buf)) { vprint("file %s does not exist\n", line); continue; @@ -2218,27 +2252,41 @@ int pacman_remove(pacdb_t *db, PMList *targets) /* this is okay, other packages are probably using it. */ } } else { - /* if the file is flagged, back it up to .pacsave */ - if(nb) { - if(pmo_upgrade) { - /* we're upgrading so just leave the file as is. pacman_add() will handle it */ - } else { - if(!pmo_nosave) { - newpath = (char*)realloc(newpath, strlen(line)+strlen(".pacsave")+1); - sprintf(newpath, "%s.pacsave", line); - rename(line, newpath); - logaction(stderr, "warning: %s saved as %s", line, newpath); + /* check the "skip list" before removing the file + * + * see the big comment block in db_find_conflicts() for an explanation + */ + int skipit = 0; + for(j = skiplist; j; j = j->next) { + if(!strcmp(file, (char*)j->data)) { + skipit = 1; + } + } + if(skipit) { + vprint("skipping removal of %s (it has moved to another package)\n", file); + } else { + /* if the file is flagged, back it up to .pacsave */ + if(nb) { + if(pmo_upgrade) { + /* we're upgrading so just leave the file as is. pacman_add() will handle it */ } else { - /*vprint(" unlinking %s\n", line);*/ - if(unlink(line)) { - perror("cannot remove file"); + if(!pmo_nosave) { + newpath = (char*)realloc(newpath, strlen(line)+strlen(".pacsave")+1); + sprintf(newpath, "%s.pacsave", line); + rename(line, newpath); + logaction(stderr, "warning: %s saved as %s", line, newpath); + } else { + /*vprint(" unlinking %s\n", line);*/ + if(unlink(line)) { + perror("cannot remove file"); + } } } - } - } else { - /*vprint(" unlinking %s\n", line);*/ - if(unlink(line)) { - perror("cannot remove file"); + } else { + /*vprint(" unlinking %s\n", line);*/ + if(unlink(line)) { + perror("cannot remove file"); + } } } } @@ -2252,27 +2300,11 @@ int pacman_remove(pacdb_t *db, PMList *targets) } /* remove the package from the database */ - snprintf(line, PATH_MAX, "%s%s/%s/%s-%s", pmo_root, pmo_dbpath, db->treename, - info->name, info->version); - - /* DESC */ - snprintf(pm_install, PATH_MAX, "%s/desc", line); - unlink(pm_install); - /* FILES */ - snprintf(pm_install, PATH_MAX, "%s/files", line); - unlink(pm_install); - /* DEPENDS */ - snprintf(pm_install, PATH_MAX, "%s/depends", line); - unlink(pm_install); - /* INSTALL */ - snprintf(pm_install, PATH_MAX, "%s/install", line); - unlink(pm_install); - /* directory */ - rmdir(line); + db_remove(db, info); /* update dependency packages' REQUIREDBY fields */ for(lp = info->depends; lp; lp = lp->next) { - PMList *j; + PMList *k; if(splitdep((char*)lp->data, &depend)) { continue; @@ -2298,9 +2330,9 @@ int pacman_remove(pacdb_t *db, PMList *targets) } } /* splice out this entry from requiredby */ - for(j = depinfo->requiredby; j; j = j->next) { - if(!strcmp((char*)j->data, info->name)) { - depinfo->requiredby = list_remove(depinfo->requiredby, j); + for(k = depinfo->requiredby; k; k = k->next) { + if(!strcmp((char*)k->data, info->name)) { + depinfo->requiredby = list_remove(depinfo->requiredby, k); break; } } @@ -2673,6 +2705,7 @@ PMList* removedeps(pacdb_t *db, PMList *targs) FREELIST(k); } if(is_pkgin(dep, targs)) { + FREEPKG(dep); continue; } /* see if it was explicitly installed */ @@ -2687,10 +2720,11 @@ PMList* removedeps(pacdb_t *db, PMList *targs) if(!is_pkgin(dummy, targs)) { needed = 1; } + FREEPKG(dummy); } + FREEPKG(dep); if(!needed) { /* add it to the target list */ - freepkg(dep); dep = db_scan(db, depend.name, INFRQ_ALL); newtargs = list_add(newtargs, dep); newtargs = removedeps(db, newtargs); @@ -2922,6 +2956,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets) strncpy(miss->depend.version, depend.version, 64); if(!list_isin(baddeps, miss)) { baddeps = list_add(baddeps, miss); + } else { + FREE(miss); } } FREEPKG(p); @@ -2969,6 +3005,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets) strncpy(miss->depend.name, dp->name, 256); if(!list_isin(baddeps, miss)) { baddeps = list_add(baddeps, miss); + } else { + FREE(miss); } } } @@ -3002,6 +3040,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets) strncpy(miss->depend.name, otp->name, 256); if(!list_isin(baddeps, miss)) { baddeps = list_add(baddeps, miss); + } else { + FREE(miss); } } } @@ -3036,6 +3076,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets) strncpy(miss->depend.name, info->name, 256); if(!list_isin(baddeps, miss)) { baddeps = list_add(baddeps, miss); + } else { + FREE(miss); } } } @@ -3063,6 +3105,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets) strncpy(miss->depend.name, k->data, 256); if(!list_isin(baddeps, miss)) { baddeps = list_add(baddeps, miss); + } else { + FREE(miss); } } }*/ @@ -3178,6 +3222,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets) strncpy(miss->depend.version, depend.version, 64); if(!list_isin(baddeps, miss)) { baddeps = list_add(baddeps, miss); + } else { + FREE(miss); } } } @@ -3200,6 +3246,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets) strncpy(miss->depend.name, (char*)j->data, 256); if(!list_isin(baddeps, miss)) { baddeps = list_add(baddeps, miss); + } else { + FREE(miss); } } } @@ -3326,10 +3374,10 @@ int runscriptlet(char *installfn, char *script, char *ver, char *oldver) vprint("Executing %s script...\n", script); if(oldver) { - snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s %s\" | chroot %s /bin/sh", + snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s %s\" | /usr/sbin/chroot %s /bin/sh", scriptpath, script, ver, oldver, pmo_root); } else { - snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s\" | chroot %s /bin/sh", + snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s\" | /usr/sbin/chroot %s /bin/sh", scriptpath, script, ver, pmo_root); } vprint("%s\n", cmdline); -- cgit v1.2.3-24-g4f1b