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/db.c | 125 ++++++++++++++++++--------- src/db.h | 7 +- src/list.c | 17 ++-- src/pacconf.h | 2 +- src/pacman.c | 158 +++++++++++++++++++++------------ src/pacman.h | 2 +- src/pacsync.c | 7 ++ src/strhash.c | 273 ++++++++++++++++++++++++++++++---------------------------- src/strhash.h | 1 + 9 files changed, 349 insertions(+), 243 deletions(-) (limited to 'src') diff --git a/src/db.c b/src/db.c index 8dd12c98..005498c4 100644 --- a/src/db.c +++ b/src/db.c @@ -137,21 +137,32 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq) char *ptr = NULL; int found = 0; - /* hash table for caching directory names */ - static strhash_t* htable = NULL; - - if (!htable) - htable = new_strhash(951); + /* initialize the hash table */ + if(!db_htable) { + db_htable = new_strhash(951); + } snprintf(path, PATH_MAX, "%s/", db->path); path_len = strlen(path); + /* TODO: + * + * Currently we're using a hash table to cache the directory + * name of each package we db_scan() for. This saves us from + * having to scan the db directory for the full + * pkgname-pkgver-pkgrel dir name, but we still have to issue + * a db_read() call to get the actual package data. + * + * A more efficient method may be to cache the package data + * itself. + */ + if(target != NULL) { /* search for a specific package (by name only) */ /* See if we have the path cached. */ strcat(path, target); - if (strhash_isin(htable, path)) { + if(strhash_isin(db_htable, path)) { struct dirent* pkgdir; pkginfo_t* pkg; @@ -159,7 +170,7 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq) * Actually it only uses the d_name field. */ MALLOC(pkgdir, sizeof(struct dirent)); - strcpy(pkgdir->d_name, strhash_get(htable, path)); + strcpy(pkgdir->d_name, strhash_get(db_htable, path)); pkg = db_read(db, pkgdir, inforeq); FREE(pkgdir); @@ -242,8 +253,8 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq) * data: xrally-1.1.1-1 */ - if (!strhash_isin(htable, path)) { - strhash_add(htable, strdup(path), strdup(ent->d_name)); + if(!strhash_isin(db_htable, path)) { + strhash_add(db_htable, strdup(path), strdup(ent->d_name)); } } } @@ -595,6 +606,40 @@ int db_write(pacdb_t *db, pkginfo_t *info, unsigned int inforeq) return(0); } +/* + * Remove a package record from the database + */ +void db_remove(pacdb_t *db, pkginfo_t *target) +{ + char topdir[PATH_MAX]; + char path[PATH_MAX]; + + snprintf(topdir, PATH_MAX, "%s/%s-%s", db->path, + target->name, target->version); + + /* DESC */ + snprintf(path, PATH_MAX, "%s/desc", topdir); + unlink(path); + /* FILES */ + snprintf(path, PATH_MAX, "%s/files", topdir); + unlink(path); + /* DEPENDS */ + snprintf(path, PATH_MAX, "%s/depends", topdir); + unlink(path); + /* INSTALL */ + snprintf(path, PATH_MAX, "%s/install", topdir); + unlink(path); + /* directory */ + rmdir(topdir); + + /* remove the entry from the hash table */ + if(db_htable) { + /*clear_strhash(db_htable);*/ + snprintf(topdir, PATH_MAX, "%s/%s", db->path, target->name); + strhash_remove(db_htable, topdir); + } +} + void db_search(pacdb_t *db, PMList *cache, const char *treename, PMList *needles) { PMList *i, *j; @@ -655,7 +700,7 @@ void db_search(pacdb_t *db, PMList *cache, const char *treename, PMList *needles } -PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root) +PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root, PMList **skip_list) { PMList *i, *j, *k; char *filestr = NULL; @@ -663,6 +708,7 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root) char *str = NULL; struct stat buf, buf2; PMList *conflicts = NULL; + strhash_t** htables; int target_num = 0; int d = 0; @@ -680,42 +726,12 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root) for(d = 0, i = targets; i; i = i->next, d++) { htables[d] = new_strhash(151); - strhash_add_list(htables[d], ((pkginfo_t*)i->data)->files); } htables[target_num] = new_strhash(151); - /* CHECK 1: check every db package against every target package */ - /* XXX: I've disabled the database-against-targets check for now, as the - * many many strcmp() calls slow it down heavily and most of the - * checking is redundant to the targets-against-filesystem check. - * This will be re-enabled if I can improve performance significantly. - * - pkginfo_t *info = NULL; - char *dbstr = NULL; - rewinddir(db->dir); - - while((info = db_scan(db, NULL, INFRQ_DESC | INFRQ_FILES)) != NULL) { - for(i = info->files; i; i = i->next) { - dbstr = (char*)i->data; - - if(dbstr == NULL || rindex(dbstr, '/') == dbstr+strlen(dbstr)-1) - continue; - - for(d = 0, j = targets; j; j = j->next, d++) { - pkginfo_t *targ = (pkginfo_t*)j->data; - if(strcmp(info->name, targ->name) && strhash_isin(htables[d], dbstr)) { - MALLOC(str, 512); - snprintf(str, 512, "%s: exists in \"%s\" (target) and \"%s\" (installed)", dbstr, - targ->name, info->name); - conflicts = list_add(conflicts, str); - } - } - } - }*/ - - /* CHECK 2: check every target against every target */ + /* CHECK 1: check every target against every target */ for(d = 0, i = targets; i; i = i->next, d++) { pkginfo_t *p1 = (pkginfo_t*)i->data; for(e = d, j = i; j; j = j->next, e++) { @@ -741,7 +757,7 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root) } } - /* CHECK 3: check every target against the filesystem */ + /* CHECK 2: check every target against the filesystem */ for(i = targets; i; i = i->next) { pkginfo_t *p = (pkginfo_t*)i->data; pkginfo_t *dbpkg = NULL; @@ -769,6 +785,7 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root) snprintf(str, PATH_MAX, "%s%s", root, (char*)k->data); stat(str, &buf2); if(buf.st_ino == buf2.st_ino && buf.st_dev == buf2.st_dev) { + printf("inodes match: %s and %s\n", path, str); ok = 1; } } @@ -785,7 +802,26 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root) dbpkg2 = db_scan(db, p1->name, INFRQ_DESC | INFRQ_FILES); /* If it used to exist in there, but doesn't anymore */ if(dbpkg2 && !is_in(filestr, p1->files) && is_in(filestr, dbpkg2->files)) { + /*printf("file %s moved from %s to %s\n", filestr, p1->name, p->name);*/ + ok = 1; + /* Add to the "skip list" of files that we shouldn't remove during an upgrade. + * + * This is a workaround for the following scenario: + * + * - the old package A provides file X + * - the new package A does not + * - the new package B provides file X + * - package A depends on B, so B is upgraded first + * + * Package B is upgraded, so file X is installed. Then package A + * is upgraded, and it *removes* file X, since it no longer exists + * in package A. + * + * Our workaround is to scan through all "old" packages and all "new" + * ones, looking for files that jump to different packages. + */ + *skip_list = list_add(*skip_list, filestr); } FREEPKG(dbpkg2); } @@ -801,6 +837,11 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root) FREEPKG(dbpkg); } + /* free up the hash tables */ + for(d = 0; d <= target_num; d++) { + free_strhash(htables[d]); + } + return(conflicts); } diff --git a/src/db.h b/src/db.h index 402280f8..f7d2a1a7 100644 --- a/src/db.h +++ b/src/db.h @@ -22,6 +22,7 @@ #define _PAC_DB_H #include +#include "strhash.h" /* info requests for db_read */ #define INFRQ_DESC 0x01 @@ -35,6 +36,9 @@ typedef struct __pacdb_t { DIR* dir; } pacdb_t; +/* hash table for caching db_scan() results */ +static strhash_t* db_htable; + pacdb_t* db_open(char *root, char *dbpath, char *treename); void db_close(pacdb_t *db); int db_getlastupdate(const char *dbpath, char *ts); @@ -43,8 +47,9 @@ PMList* db_loadpkgs(pacdb_t *db); pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq); pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq); int db_write(pacdb_t *db, pkginfo_t *info, unsigned int inforeq); +void db_remove(pacdb_t *db, pkginfo_t *target); void db_search(pacdb_t *db, PMList *cache, const char *treename, PMList *needles); -PMList* db_find_conflicts(pacdb_t *db, PMList* targets, char *root); +PMList* db_find_conflicts(pacdb_t *db, PMList* targets, char *root, PMList **skip_list); PMList *whatprovides(pacdb_t *db, char* package); PMList *find_groups(pacdb_t *db); PMList *pkg_ingroup(pacdb_t *db, char *group); diff --git a/src/list.c b/src/list.c index 689a17d3..49c07f51 100644 --- a/src/list.c +++ b/src/list.c @@ -67,17 +67,14 @@ PMList* list_new() void list_free(PMList *list) { - if(list == NULL) { - return; - } - if(list->data != NULL) { - free(list->data); - list->data = NULL; - } - if(list->next != NULL) { - list_free(list->next); + PMList *ptr, *it = list; + + while(it) { + ptr = it->next; + free(it->data); + free(it); + it = ptr; } - free(list); return; } diff --git a/src/pacconf.h b/src/pacconf.h index ceab2044..2274b9ec 100644 --- a/src/pacconf.h +++ b/src/pacconf.h @@ -22,7 +22,7 @@ #define _PAC_PACCONF_H #ifndef PACVER -#define PACVER "2.9.5" +#define PACVER "2.9.6" #endif #ifndef PACDBDIR 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); diff --git a/src/pacman.h b/src/pacman.h index 9e22bb31..79106eb1 100644 --- a/src/pacman.h +++ b/src/pacman.h @@ -33,7 +33,7 @@ #define min(X, Y) ((X) < (Y) ? (X) : (Y)) int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly); -int pacman_remove(pacdb_t *db, PMList *targets); +int pacman_remove(pacdb_t *db, PMList *targets, PMList *skiplist); int pacman_upgrade(pacdb_t *db, PMList *targets, PMList *dependonly); int pacman_query(pacdb_t *db, PMList *targets); int pacman_sync(pacdb_t *db, PMList *targets); diff --git a/src/pacsync.c b/src/pacsync.c index c2ff4bee..4b1f1b53 100644 --- a/src/pacsync.c +++ b/src/pacsync.c @@ -441,6 +441,13 @@ int downloadfiles_forreal(PMList *servers, const char *localpath, snprintf(completefile, PATH_MAX, "%s/%s", localpath, fn); rename(output, completefile); } else if(filedone < 0) { + if(!pmo_xfercommand) { + if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) { + FtpQuit(control); + } else if(!strcmp(server->protocol, "http") || (pmo_proxyhost && strcmp(server->protocol, "file"))) { + HttpQuit(control); + } + } return(-1); } printf("\n"); diff --git a/src/strhash.c b/src/strhash.c index 1ee5498c..01e172a4 100644 --- a/src/strhash.c +++ b/src/strhash.c @@ -1,22 +1,22 @@ /* evtgen string hash functions. - Copyright (C) 2003 Julien Olivain and LSV, CNRS UMR 8643 & ENS Cachan. + Copyright (C) 2003 Julien Olivain and LSV, CNRS UMR 8643 & ENS Cachan. - This file is part of evtgen. + This file is part of evtgen. - evtgen is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + evtgen is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. - evtgen is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + evtgen is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with evtgen; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -*/ + You should have received a copy of the GNU General Public License + along with evtgen; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ /* Copyright (C) 2004 Tommi Rantala * @@ -24,8 +24,8 @@ */ /* -** strhash.c -- string hash utility functions -*/ + ** strhash.c -- string hash utility functions + */ #include #include @@ -35,161 +35,168 @@ #include "list.h" #include "strhash.h" -void -strhash_add_list(strhash_t *hash, PMList* list) +void strhash_add_list(strhash_t *hash, PMList* list) { - for(; list; list = list->next) + for(; list; list = list->next) { strhash_add(hash, list->data, NULL); + } } -strhash_t * -new_strhash(size_t hsize) +strhash_t* new_strhash(size_t hsize) { - strhash_t *h; + strhash_t *h; - MALLOC(h, sizeof (strhash_t)); - h->size = hsize; - h->elmts = 0; - h->hash = DEFAULT_STRHASH_FUNCTION; - MALLOC(h->htable, hsize * sizeof (strhash_elmt_t *)); - memset(h->htable, 0, hsize * sizeof(strhash_elmt_t *)); + MALLOC(h, sizeof(strhash_t)); + h->size = hsize; + h->elmts = 0; + h->hash = DEFAULT_STRHASH_FUNCTION; + MALLOC(h->htable, hsize * sizeof(strhash_elmt_t *)); + memset(h->htable, 0, hsize * sizeof(strhash_elmt_t *)); - return (h); + return(h); } -void -clear_strhash(strhash_t *hash) +void clear_strhash(strhash_t *hash) { - int i; - strhash_elmt_t *tmp; - strhash_elmt_t *tmp_next; - - for (i = 0; i < hash->size; i++) - { - tmp = hash->htable[i]; - while (tmp) - { - tmp_next = tmp->next; - free(tmp); - tmp = tmp_next; - } - } - hash->elmts = 0; - memset(hash->htable, 0, hash->size * sizeof (void *)); + int i; + strhash_elmt_t *tmp; + strhash_elmt_t *tmp_next; + + for(i = 0; i < hash->size; i++) { + tmp = hash->htable[i]; + while(tmp) { + tmp_next = tmp->next; + free(tmp); + tmp = tmp_next; + } + } + hash->elmts = 0; + memset(hash->htable, 0, hash->size * sizeof(void *)); } - -void -free_strhash(strhash_t *hash) +void free_strhash(strhash_t *hash) { - int i; - strhash_elmt_t *tmp; - strhash_elmt_t *tmp_next; - - for (i = 0; i < hash->size; i++) - { - tmp = hash->htable[i]; - while (tmp) - { - tmp_next = tmp->next; - free(tmp); - tmp = tmp_next; - } - } - - free(hash->htable); - free(hash); + int i; + strhash_elmt_t *tmp; + strhash_elmt_t *tmp_next; + + for(i = 0; i < hash->size; i++) { + tmp = hash->htable[i]; + while(tmp) { + tmp_next = tmp->next; + free(tmp); + tmp = tmp_next; + } + } + + free(hash->htable); + free(hash); } -void -strhash_add(strhash_t *hash, char *key, char *data) +void strhash_add(strhash_t *hash, char *key, char *data) { - strhash_elmt_t *elmt; - unsigned long hcode; + strhash_elmt_t *elmt; + unsigned long hcode; - MALLOC(elmt, sizeof (strhash_elmt_t)); - elmt->key = key; - elmt->data = data; + MALLOC(elmt, sizeof(strhash_elmt_t)); + elmt->key = key; + elmt->data = data; + + hcode = hash->hash(key) % hash->size; + elmt->next = hash->htable[hcode]; + hash->htable[hcode] = elmt; + hash->elmts++; +} - hcode = hash->hash(key) % hash->size; - elmt->next = hash->htable[hcode]; - hash->htable[hcode] = elmt; - hash->elmts++; +void strhash_remove(strhash_t *hash, char *key) +{ + unsigned long hcode; + strhash_elmt_t *elmt; + strhash_elmt_t *prev = NULL; + + hcode = hash->hash(key) % hash->size; + + elmt = hash->htable[hcode]; + for(; elmt; elmt = elmt->next) { + if(!strcmp(key, elmt->key)) { + if(prev) { + prev->next = elmt->next; + } else { + hash->htable[hcode] = elmt->next; + } + FREE(elmt); + return; + } + prev = elmt; + } } /* 1: Yes, the key exists in the hash table. - * 0: No, its not here. + * 0: No, it's not here. */ - -int -strhash_isin(strhash_t *hash, char* key) +int strhash_isin(strhash_t *hash, char* key) { - strhash_elmt_t *elmt; + strhash_elmt_t *elmt; - elmt = hash->htable[hash->hash(key) % hash->size]; - for (; elmt; elmt = elmt->next) - { - if (!strcmp(key, elmt->key)) - return 1; - } + elmt = hash->htable[hash->hash(key) % hash->size]; + for(; elmt; elmt = elmt->next) { + if(!strcmp(key, elmt->key)) { + return 1; + } + } - return 0; + return 0; } -char* -strhash_get(strhash_t *hash, char* key) +char* strhash_get(strhash_t *hash, char* key) { - strhash_elmt_t *elmt; + strhash_elmt_t *elmt; - elmt = hash->htable[hash->hash(key) % hash->size]; - for (; elmt; elmt = elmt->next) - { - if (!strcmp(key, elmt->key)) - return elmt->data; - } + elmt = hash->htable[hash->hash(key) % hash->size]; + for(; elmt; elmt = elmt->next) { + if(!strcmp(key, elmt->key)) { + return elmt->data; + } + } - return NULL; + return NULL; } /* -** fast hash function samples -*/ - -unsigned long -strhash_pjw(char *key) + ** fast hash function samples + */ +unsigned long strhash_pjw(char *key) { - unsigned long h; - unsigned long g; - - h = 0; - while (*key) - { - h = (h << 4) + *key++; - if ((g = h & 0xF0000000U) != 0) - { - h = h ^ (g >> 24); - h = h ^ g; - } - } - - return (h); + unsigned long h; + unsigned long g; + + h = 0; + while(*key) { + h = (h << 4) + *key++; + if((g = h & 0xF0000000U) != 0) { + h = h ^ (g >> 24); + h = h ^ g; + } + } + + return (h); } -int -strhash_collide_count(strhash_t *hash) +int strhash_collide_count(strhash_t *hash) { - int count; - int i; + int count; + int i; - count = 0; - for (i = 0; i < hash->size; i++) - { - strhash_elmt_t *tmp; + count = 0; + for(i = 0; i < hash->size; i++) { + strhash_elmt_t *tmp; - for (tmp = hash->htable[i]; tmp; tmp = tmp->next) - if (tmp->next) - count++; - } + for(tmp = hash->htable[i]; tmp; tmp = tmp->next) { + if(tmp->next) { + count++; + } + } + } - return (count); + return(count); } diff --git a/src/strhash.h b/src/strhash.h index 65b7f4e1..9c2d63ec 100644 --- a/src/strhash.h +++ b/src/strhash.h @@ -55,6 +55,7 @@ void strhash_add_list(strhash_t *hash, PMList* list); strhash_t *new_strhash(size_t hsize); void free_strhash(strhash_t *hash); void clear_strhash(strhash_t *hash); +void strhash_remove(strhash_t *hash, char *key); void strhash_add(strhash_t *hash, char *key, char *data); int strhash_isin(strhash_t *hash, char* key); char* strhash_get(strhash_t *hash, char* key); -- cgit v1.2.3-24-g4f1b