From 08962d40c076e0343af724db6243c81cff2c7c25 Mon Sep 17 00:00:00 2001 From: Judd Vinet Date: Fri, 19 Aug 2005 22:41:20 +0000 Subject: Imported from pacman-2.9.7-TEST.tar.gz --- ChangeLog | 12 ++++- Makefile.in | 2 +- doc/makepkg.8.in | 10 ++++ doc/pacman.8.in | 15 ++++-- etc/makepkg.conf | 4 +- scripts/gensync | 2 +- scripts/makepkg | 41 +++++++++++--- scripts/makeworld | 2 +- scripts/pacman-optimize | 8 +-- scripts/updatesync | 2 +- src/db.c | 140 +++++++++++++++++++++++++++--------------------- src/md5.h | 2 +- src/pacconf.h | 2 +- src/package.c | 10 ++-- src/package.h | 2 +- src/pacman.c | 40 ++++++++++---- src/util.c | 97 +++++++++++++++++++++++++++++++++ src/util.h | 1 + 18 files changed, 292 insertions(+), 100 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f92d4ed..0904c43d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ VERSION DESCRIPTION ----------------------------------------------------------------------------- +2.9.7 - patch from Miklos Vanja fixed md5sums on x86_64 + - patch from Miklos Vanja adds --sudosync to makepkg + - changed license field to operate as an array, not a string + - added more logic for file conflict checks - if one target + is a file and the other is a directory, then it's a conflict + - fixed the integrity check in pacman-optimize + - reverted NoUpgrade to old behaviour and instead, added the + NoExtract directive to pacman.conf, which prevents a file + from ever being extracted on to the system + eg, NoExtract = home/httpd/html/index.html 2.9.6 - added a pacman-optimize script to try and defragment the DB - modified NoUpgrade behaviour to avoid extracting files that are missing from the filesystem -- this helps in @@ -9,7 +19,7 @@ VERSION DESCRIPTION moved from one package to another - add db_remove() which is responsible for clearing out stale hash table entries when packages are removed - - added cache support to makepkg + - added ccache support to makepkg - patch from Aurelien Foret fixes a few memory leaks 2.9.5 - bugfix: missing files after re-ordering packages wrt deps with --upgrade diff --git a/Makefile.in b/Makefile.in index 34c463f7..ed8d2190 100644 --- a/Makefile.in +++ b/Makefile.in @@ -34,7 +34,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ -PACVER = 2.9.6 +PACVER = 2.9.7 TOPDIR = @srcdir@ SRCDIR = $(TOPDIR)/src/ diff --git a/doc/makepkg.8.in b/doc/makepkg.8.in index 569f3596..0de31bf1 100644 --- a/doc/makepkg.8.in +++ b/doc/makepkg.8.in @@ -342,6 +342,11 @@ Do not perform any dependency checks. This will let you override/ignore any dependencies required. There's a good chance this option will break the build process if all of the dependencies aren't installed. .TP +.B "\-e, \-\-noextract" +Do not extract source files. Instead, use whatever already exists in the +src/ directory. This is handy if you want to go into src and manually +patch/tweak code, then make a package out of the result. +.TP .B "\-f, \-\-force" \fBmakepkg\fP will not build a package if a \fIpkgname-pkgver-pkgrel.pkg.tar.gz\fP file already exists in the build directory. You can override this behaviour with @@ -384,6 +389,11 @@ or run-time dependencies, it will run pacman to try and resolve them. If succes pacman will download the missing packages from a package repository and install them for you. .TP +.B "\-S, \-\-sudosync" +Install missing dependencies using pacman and sudo. This is the same as \fB-s\fP +except that makepkg will call pacman with sudo. This means you don't have to +build as root to use dependency auto-resolution. +.TP .B "\-w " Write the resulting package file to the directory \fI\fP instead of the current working directory. diff --git a/doc/pacman.8.in b/doc/pacman.8.in index 09c47d50..32e04e3a 100644 --- a/doc/pacman.8.in +++ b/doc/pacman.8.in @@ -1,4 +1,4 @@ -.TH pacman 8 "September 17, 2004" "pacman #VERSION#" "" +.TH pacman 8 "July 6, 2005" "pacman #VERSION#" "" .SH NAME pacman \- package manager utility .SH SYNOPSIS @@ -106,9 +106,9 @@ List all files in the specified repositories. Multiple repositories can be specified on the command line. .TP .B "\-p, \-\-print-uris" -Print out URIs for each specified package and its dependencies. These -can be piped to a file and downloaded at a later time, using a program -like wget. +Print out URIs for each package that will be installed, including any +dependencies that have yet to be installed. These can be piped to a +file and downloaded at a later time, using a program like wget. .TP .B "\-s, \-\-search " This will search each package in the package list for names or descriptions @@ -272,6 +272,13 @@ Disables passive ftp connections when downloading packages. (aka Active Mode) All files listed with a \fBNoUpgrade\fP directive will never be touched during a package install/upgrade. \fINote:\fP do not include the leading slash when specifying files. .TP +.B "NoExtract = [file] ..." +All files listed with a \fBNoExtract\fP directive will never be extracted from +a package into the filesystem. This can be useful when you don't want part of +a package to be installed. For example, if your httpd root uses an index.php, +then you would not want the index.html file to be extracted from the apache +package. +.TP .B "UseSyslog" Log action messages through syslog(). This will insert pacman log entries into your /var/log/messages or equivalent. diff --git a/etc/makepkg.conf b/etc/makepkg.conf index d43b0e67..5f787397 100644 --- a/etc/makepkg.conf +++ b/etc/makepkg.conf @@ -12,8 +12,8 @@ export CHOST="i686-pc-linux-gnu" # Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon exclusive (binaries # will use the P6 instruction set and only run on P6+ systems) -export CFLAGS="-march=i686 -O2 -pipe -Wl,-O1" -export CXXFLAGS="-march=i686 -O2 -pipe -Wl,-O1" +export CFLAGS="-march=i686 -O2 -pipe" +export CXXFLAGS="-march=i686 -O2 -pipe" # Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon optimized (but binaries # will run on any x86 system) #export CFLAGS="-mcpu=i686 -O2 -pipe" diff --git a/scripts/gensync b/scripts/gensync index 0ebc1386..3cfcbcaa 100755 --- a/scripts/gensync +++ b/scripts/gensync @@ -20,7 +20,7 @@ # USA. # -myver='2.9.6' +myver='2.9.7' usage() { echo "gensync $myver" diff --git a/scripts/makepkg b/scripts/makepkg index 31e78f97..0361e8bd 100755 --- a/scripts/makepkg +++ b/scripts/makepkg @@ -20,7 +20,7 @@ # USA. # -myver='2.9.6' +myver='2.9.7' startdir=`pwd` PKGDEST=$startdir USE_COLOR="n" @@ -108,7 +108,7 @@ handledeps() { local missingdeps=0 local deplist="$*" local haveperm=0 - if [ "`id -u`" = "0" -a "$INFAKEROOT" != "1" ]; then + if [ \( "`id -u`" = "0" -a "$INFAKEROOT" != "1" \) -o "$DEP_SUDO" = 1 ]; then haveperm=1 fi @@ -122,6 +122,15 @@ handledeps() { exit 1 fi # TODO: check deps again to make sure they were resolved + elif [ "$DEP_SUDO" = "1" ]; then + # install missing deps from binary packages (using pacman -S and sudo) + msg "Installing missing dependencies..." + sudo pacman -D $deplist + if [ "$?" = "127" ]; then + error "Failed to install missing dependencies." + exit 1 + fi + # TODO: check deps again to make sure they were resolved elif [ "$DEP_SRC" = "1" ]; then # install missing deps by building them from source. # we look for each package name in $ABSROOT and build it. @@ -163,8 +172,8 @@ handledeps() { fi elif [ "$deplist" != "" -a $haveperm -eq 0 ]; then if [ "$DEP_SRC" = "1" -o "$DEP_BIN" = "1" ]; then - warning "Cannot auto-install missing dependencies as a normal user!" - plain "Run makepkg as root to resolve dependencies automatically." + warning "Cannot auto-install missing dependencies as a normal user without sudo!" + plain "Run makepkg as root or with -S to resolve dependencies automatically." fi missingdeps=1 fi @@ -191,6 +200,7 @@ usage() { echo " -p Use an alternate build script (instead of PKGBUILD)" echo " -r, --rmdeps Remove installed dependencies after a successful build" echo " -s, --syncdeps Install missing dependencies with pacman" + echo " -S, --sudosync Install missing dependencies with pacman and sudo" echo " -w Write package to instead of the working dir" echo echo " if -p is not specified, makepkg will look for a PKGBUILD" @@ -205,6 +215,7 @@ CLEANCACHE=0 INSTALL=0 GENMD5=0 DEP_BIN=0 +DEP_SUDO=0 DEP_SRC=0 NODEPS=0 FORCE=0 @@ -221,6 +232,7 @@ while [ "$#" -ne "0" ]; do --clean) CLEANUP=1 ;; --cleancache) CLEANCACHE=1 ;; --syncdeps) DEP_BIN=1 ;; + --sudosync) DEP_SUDO=1 ;; --builddeps) DEP_SRC=1 ;; --nodeps) NODEPS=1 ;; --noextract) NOEXTRACT=1 ;; @@ -240,7 +252,7 @@ while [ "$#" -ne "0" ]; do exit 1 ;; -*) - while getopts "cCsbdehifgj:mnorp:w:-" opt; do + while getopts "cCsSbdehifgj:mnorp:w:-" opt; do case $opt in c) CLEANUP=1 ;; C) CLEANCACHE=1 ;; @@ -261,6 +273,7 @@ while [ "$#" -ne "0" ]; do p) BUILDSCRIPT=$OPTARG ;; r) RMDEPS=1 ;; s) DEP_BIN=1 ;; + S) DEP_SUDO=1 ;; w) PKGDEST=$OPTARG ;; -) OPTIND=0 @@ -280,6 +293,12 @@ while [ "$#" -ne "0" ]; do shift done +# check for sudo +if [ "$DEP_SUDO" = "1" -a ! "`type -p sudo`" ]; then + error "Cannot find the sudo binary! Is sudo installed?" + exit 1 +fi + # convert a (possibly) relative path to absolute cd $PKGDEST 2>/dev/null if [ $? -ne 0 ]; then @@ -320,6 +339,10 @@ if [ `echo $pkgrel | grep '-'` ]; then error "pkgrel is not allowed to contain hyphens." exit 1 fi +if [ "$install" -a ! -f "$install" ]; then + error "install scriptlet ($install) does not exist." + exit 1 +fi if [ -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz -a "$FORCE" = "0" -a "$GENMD5" = "0" ]; then if [ "$INSTALL" = "1" ]; then @@ -631,7 +654,6 @@ echo "pkgname = $pkgname" >>.PKGINFO echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO echo "pkgdesc = $pkgdesc" >>.PKGINFO echo "url = $url" >>.PKGINFO -echo "license = $license" >>.PKGINFO echo "builddate = $builddate" >>.PKGINFO echo "packager = $packager" >>.PKGINFO echo "size = $size" >>.PKGINFO @@ -639,6 +661,9 @@ if [ "$CARCH" != "" ]; then echo "arch = $CARCH" >>.PKGINFO fi +for it in "${license[@]}"; do + echo "license = $it" >>.PKGINFO +done for it in "${replaces[@]}"; do echo "replaces = $it" >>.PKGINFO done @@ -688,6 +713,10 @@ fi if [ "$RMDEPS" = "1" -a "`id -u`" = "0" -a "$INFAKEROOT" != "1" ]; then msg "Removing installed dependencies..." pacman -R $makedeplist $deplist + +elif [ "$RMDEPS" = "1" -a "$DEP_SUDO" = "1" ]; then + msg "Removing installed dependencies..." + sudo pacman -R $makedeplist $deplist fi msg "Finished making: $pkgname (`date`)" diff --git a/scripts/makeworld b/scripts/makeworld index 30418afd..7d4c762c 100755 --- a/scripts/makeworld +++ b/scripts/makeworld @@ -20,7 +20,7 @@ # USA. # -version="2.9.6" +version="2.9.7" toplevel=`pwd` usage() { diff --git a/scripts/pacman-optimize b/scripts/pacman-optimize index b9573cbb..cb321f2c 100755 --- a/scripts/pacman-optimize +++ b/scripts/pacman-optimize @@ -20,7 +20,7 @@ # USA. # -myver='2.9.6' +myver='2.9.7' usage() { echo "pacman-optimize $myver" @@ -77,7 +77,7 @@ touch /tmp/pacman.lck # step 1: sum the old db echo "==> md5sum'ing the old database..." -tar c $dbroot 2>/dev/null | md5sum >/tmp/pacsums.old +tar --same-order -c $dbroot 2>/dev/null | md5sum >/tmp/pacsums.old # step 1: copy the entire db directory to a new one echo "==> copying $dbroot..." @@ -87,7 +87,7 @@ cp -a $dbroot $dbroot.new || die_r "error copying $dbroot" echo "==> md5sum'ing the new database..." mv $dbroot $dbroot.bak || die_r "error renaming $dbroot" mv $dbroot.new $dbroot || die_r "error renaming $dbroot.new" -tar c $dbroot 2>/dev/null | md5sum >/tmp/pacsums.new +tar --same-order -c $dbroot 2>/dev/null | md5sum >/tmp/pacsums.new # step 3: compare sums echo "==> checking integrity..." @@ -96,7 +96,7 @@ if [ $? -ne 0 ]; then # failed, move the old one back into place rm -rf $dbroot mv $dbroot.bak $dbroot - die_r "integrity check FAILED, reverting to old databse" + die_r "integrity check FAILED, reverting to old database" fi # step 4: remove the backup diff --git a/scripts/updatesync b/scripts/updatesync index e36d25e7..5385ed66 100755 --- a/scripts/updatesync +++ b/scripts/updatesync @@ -21,7 +21,7 @@ # USA. # -myver='2.9.6' +myver='2.9.7' usage() { echo "updatesync $myver" diff --git a/src/db.c b/src/db.c index 005498c4..82e76318 100644 --- a/src/db.c +++ b/src/db.c @@ -327,12 +327,6 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq) return(NULL); } trim(info->url); - } else if(!strcmp(line, "%LICENSE%")) { - if(fgets(info->license, sizeof(info->license), fp) == NULL) { - FREEPKG(info); - return(NULL); - } - trim(info->license); } else if(!strcmp(line, "%ARCH%")) { if(fgets(info->arch, sizeof(info->arch), fp) == NULL) { FREEPKG(info); @@ -386,6 +380,11 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq) } trim(tmp); info->size = atol(tmp); + } else if(!strcmp(line, "%LICENSE%")) { + while(fgets(line, 512, fp) && strlen(trim(line))) { + char *s = strdup(line); + info->license = list_add(info->license, s); + } } else if(!strcmp(line, "%REPLACES%")) { /* the REPLACES tag is special -- it only appears in sync repositories, * not the local one. */ @@ -529,7 +528,10 @@ int db_write(pacdb_t *db, pkginfo_t *info, unsigned int inforeq) fputs("%URL%\n", fp); fprintf(fp, "%s\n\n", info->url); fputs("%LICENSE%\n", fp); - fprintf(fp, "%s\n\n", info->license); + for(lp = info->license; lp; lp = lp->next) { + fprintf(fp, "%s\n", (char*)lp->data); + } + fprintf(fp, "\n"); fputs("%ARCH%\n", fp); fprintf(fp, "%s\n\n", info->arch); fputs("%BUILDDATE%\n", fp); @@ -762,68 +764,84 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root, PMList **ski pkginfo_t *p = (pkginfo_t*)i->data; pkginfo_t *dbpkg = NULL; for(j = p->files; j; j = j->next) { + int isdir = 0; filestr = (char*)j->data; snprintf(path, PATH_MAX, "%s%s", root, filestr); - if(!stat(path, &buf) && !S_ISDIR(buf.st_mode)) { + /* is this target a file or directory? */ + if(path[strlen(path)-1] == '/') { + isdir = 1; + path[strlen(path)-1] = '\0'; + } + if(!lstat(path, &buf)) { int ok = 0; - if(dbpkg == NULL) { - dbpkg = db_scan(db, p->name, INFRQ_DESC | INFRQ_FILES); - - if(dbpkg) - strhash_add_list(htables[target_num], dbpkg->files); - } - if(dbpkg && strhash_isin(htables[target_num], filestr)) { + if(!S_ISLNK(buf.st_mode) && ((isdir && !S_ISDIR(buf.st_mode)) || (!isdir && S_ISDIR(buf.st_mode)))) { + /* if the package target is a directory, and the filesystem target + * is not (or vice versa) then it's a conflict + */ + ok = 0; + } else if(S_ISDIR(buf.st_mode)) { + /* if it's a directory, then we have no conflict */ ok = 1; - } - /* Make sure that the supposedly-conflicting file is not actually just - * a symlink that points to a path that used to exist in the package. - */ - /* Check if any part of the conflicting file's path is a symlink */ - if(dbpkg && !ok) { - MALLOC(str, PATH_MAX); - for(k = dbpkg->files; k; k = k->next) { - 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; + } else { + if(dbpkg == NULL) { + dbpkg = db_scan(db, p->name, INFRQ_DESC | INFRQ_FILES); + + if(dbpkg) + strhash_add_list(htables[target_num], dbpkg->files); + } + if(dbpkg && strhash_isin(htables[target_num], filestr)) { + ok = 1; + } + /* Make sure that the supposedly-conflicting file is not actually just + * a symlink that points to a path that used to exist in the package. + */ + /* Check if any part of the conflicting file's path is a symlink */ + if(dbpkg && !ok) { + MALLOC(str, PATH_MAX); + for(k = dbpkg->files; k; k = k->next) { + 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; + } } + FREE(str); } - FREE(str); - } - /* Check if the conflicting file has been moved to another package/target */ - if(!ok) { - /* Look at all the targets */ - for(k = targets; k && !ok; k = k->next) { - pkginfo_t *p1 = (pkginfo_t*)k->data; - /* As long as they're not the current package */ - if(strcmp(p1->name, p->name)) { - pkginfo_t *dbpkg2 = NULL; - 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);*/ + /* Check if the conflicting file has been moved to another package/target */ + if(!ok) { + /* Look at all the targets */ + for(k = targets; k && !ok; k = k->next) { + pkginfo_t *p1 = (pkginfo_t*)k->data; + /* As long as they're not the current package */ + if(strcmp(p1->name, p->name)) { + pkginfo_t *dbpkg2 = NULL; + 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); + 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); } - FREEPKG(dbpkg2); } } } diff --git a/src/md5.h b/src/md5.h index e6e4ea64..20aae92b 100644 --- a/src/md5.h +++ b/src/md5.h @@ -31,7 +31,7 @@ typedef unsigned char *POINTER; typedef unsigned short int UINT2; /* UINT4 defines a four byte word */ -typedef unsigned long int UINT4; +typedef unsigned int UINT4; /* MD5 context. */ diff --git a/src/pacconf.h b/src/pacconf.h index 2274b9ec..8c2794ff 100644 --- a/src/pacconf.h +++ b/src/pacconf.h @@ -22,7 +22,7 @@ #define _PAC_PACCONF_H #ifndef PACVER -#define PACVER "2.9.6" +#define PACVER "2.9.7" #endif #ifndef PACDBDIR diff --git a/src/package.c b/src/package.c index 5eba3a49..747a8dd5 100644 --- a/src/package.c +++ b/src/package.c @@ -197,8 +197,6 @@ int parse_descfile(char *descfile, pkginfo_t *info, PMList **backup, int output) info->groups = list_add(info->groups, strdup(ptr)); } else if(!strcmp(key, "URL")) { strncpy(info->url, ptr, sizeof(info->url)); - } else if(!strcmp(key, "LICENSE")) { - strncpy(info->license, ptr, sizeof(info->license)); } else if(!strcmp(key, "BUILDDATE")) { strncpy(info->builddate, ptr, sizeof(info->builddate)); } else if(!strcmp(key, "INSTALLDATE")) { @@ -211,6 +209,8 @@ int parse_descfile(char *descfile, pkginfo_t *info, PMList **backup, int output) char tmp[32]; strncpy(tmp, ptr, sizeof(tmp)); info->size = atol(tmp); + } else if(!strcmp(key, "LICENSE")) { + info->license = list_add(info->license, strdup(ptr)); } else if(!strcmp(key, "DEPEND")) { info->depends = list_add(info->depends, strdup(ptr)); } else if(!strcmp(key, "CONFLICT")) { @@ -244,7 +244,6 @@ pkginfo_t* newpkg() pkg->version[0] = '\0'; pkg->desc[0] = '\0'; pkg->url[0] = '\0'; - pkg->license[0] = '\0'; pkg->builddate[0] = '\0'; pkg->installdate[0] = '\0'; pkg->packager[0] = '\0'; @@ -254,6 +253,7 @@ pkginfo_t* newpkg() pkg->scriptlet = 0; pkg->force = 0; pkg->reason = REASON_EXPLICIT; + pkg->license = NULL; pkg->requiredby = NULL; pkg->conflicts = NULL; pkg->files = NULL; @@ -340,7 +340,9 @@ void dump_pkg_full(pkginfo_t *info) FREELIST(pm); printf("Packager : %s\n", info->packager); printf("URL : %s\n", info->url); - printf("License : %s\n", info->license); + pm = list_sort(info->license); + list_display("License :", pm); + FREELIST(pm); printf("Architecture : %s\n", info->arch); printf("Size : %ld\n", info->size); printf("Build Date : %s %s\n", info->builddate, strlen(info->builddate) ? "UTC" : ""); diff --git a/src/package.h b/src/package.h index ac300323..6b1b905b 100644 --- a/src/package.h +++ b/src/package.h @@ -50,7 +50,6 @@ typedef struct __pkginfo_t { char version[64]; char desc[512]; char url[256]; - char license[128]; char builddate[32]; char installdate[32]; char packager[64]; @@ -60,6 +59,7 @@ typedef struct __pkginfo_t { unsigned short scriptlet; unsigned short force; unsigned short reason; + PMList *license; PMList *replaces; PMList *groups; PMList *files; diff --git a/src/pacman.c b/src/pacman.c index 3daa1fe4..b8d8eed5 100644 --- a/src/pacman.c +++ b/src/pacman.c @@ -92,6 +92,7 @@ char *pmo_proxyhost = NULL; unsigned short pmo_proxyport = 0; char *pmo_xfercommand = NULL; PMList *pmo_noupgrade = NULL; +PMList *pmo_noextract = NULL; PMList *pmo_ignorepkg = NULL; PMList *pmo_holdpkg = NULL; unsigned short pmo_chomp = 0; @@ -1801,15 +1802,14 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly) snprintf(expath, PATH_MAX, "%s%s", pmo_root, pathname); } - /* if a file is in NoUpgrade and missing from the filesystem, - * then we never extract it. + /* if a file is in NoExtract 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); + if(is_in(pathname, pmo_noextract)) { + vprint("%s is in NoExtract - skipping\n", pathname); + logaction(stderr, "warning: %s is in NoExtract -- skipping extraction", pathname); tar_skip_regfile(tar); continue; } @@ -2105,7 +2105,7 @@ int pacman_remove(pacdb_t *db, PMList *targets, PMList *skiplist) } /* load package info from all targets */ - for(lp = targets; lp; lp = lp->next) { + for(lp = targets; lp && lp->data; lp = lp->next) { info = db_scan(db, (char*)lp->data, INFRQ_ALL); if(info == NULL) { PMList *groups; @@ -2150,6 +2150,10 @@ int pacman_remove(pacdb_t *db, PMList *targets, PMList *skiplist) } alltargs = list_add(alltargs, info); } + if(!alltargs) { + /* no targets, nothing to do */ + return(0); + } if(!pmo_nodeps && !pmo_upgrade) { vprint("checking dependencies...\n"); lp = checkdeps(db, PM_REMOVE, alltargs); @@ -2447,14 +2451,14 @@ int pacman_query(pacdb_t *db, PMList *targets) fprintf(stderr, "error: no file was specified for --owns\n"); return(1); } - if(realpath(package, rpath)) { + if(rel2abs(package, rpath, sizeof(rpath)-1)) { int gotcha = 0; rewinddir(db->dir); while((info = db_scan(db, NULL, INFRQ_DESC | INFRQ_FILES)) != NULL && !gotcha) { for(lp = info->files; lp && !gotcha; lp = lp->next) { sprintf(path, "%s%s", pmo_root, (char*)lp->data); if(!strcmp(path, rpath)) { - printf("%s is owned by %s %s\n", package, info->name, info->version); + printf("%s is owned by %s %s\n", rpath, info->name, info->version); gotcha = 1; } } @@ -2679,6 +2683,7 @@ PMList* removedeps(pacdb_t *db, PMList *targs) { PMList *i, *j, *k; PMList *newtargs = targs; + char realpkgname[255]; for(i = targs; i; i = i->next) { pkginfo_t *pkg = (pkginfo_t*)i->data; @@ -2708,6 +2713,7 @@ PMList* removedeps(pacdb_t *db, PMList *targs) FREEPKG(dep); continue; } + strncpy(realpkgname, dep->name, sizeof(realpkgname)); /* see if it was explicitly installed */ if(dep->reason == REASON_EXPLICIT) { vprint("excluding %s -- explicitly installed\n", dep->name); @@ -2725,7 +2731,7 @@ PMList* removedeps(pacdb_t *db, PMList *targs) FREEPKG(dep); if(!needed) { /* add it to the target list */ - dep = db_scan(db, depend.name, INFRQ_ALL); + dep = db_scan(db, realpkgname, INFRQ_ALL); newtargs = list_add(newtargs, dep); newtargs = removedeps(db, newtargs); } @@ -3374,10 +3380,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\" | /usr/sbin/chroot %s /bin/sh", + snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s %s\" | /usr/sbin/chroot %s /bin/bash", scriptpath, script, ver, oldver, pmo_root); } else { - snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s\" | /usr/sbin/chroot %s /bin/sh", + snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s\" | /usr/sbin/chroot %s /bin/bash", scriptpath, script, ver, pmo_root); } vprint("%s\n", cmdline); @@ -3612,6 +3618,18 @@ int parseconfig(char *configfile) } pmo_noupgrade = list_add(pmo_noupgrade, strdup(p)); vprint("config: noupgrade: %s\n", p); + } else if(!strcmp(key, "NOEXTRACT")) { + char *p = ptr; + char *q; + while((q = strchr(p, ' '))) { + *q = '\0'; + pmo_noextract = list_add(pmo_noextract, strdup(p)); + vprint("config: noextract: %s\n", p); + p = q; + p++; + } + pmo_noextract = list_add(pmo_noextract, strdup(p)); + vprint("config: noextract: %s\n", p); } else if(!strcmp(key, "IGNOREPKG")) { char *p = ptr; char *q; diff --git a/src/util.c b/src/util.c index 08241691..b68b71f2 100644 --- a/src/util.c +++ b/src/util.c @@ -219,6 +219,103 @@ int rmrf(char *path) return(0); } +/* Convert a relative path to an absolute path + * + * This function was taken from the pathconvert library and massaged + * to match our coding style. The pathconvert version is + * Copyright (c) 1997 Shigio Yamaguchi. + */ +char *rel2abs(const char *path, char *result, const size_t size) +{ + const char *pp, *bp; + /* endp points the last position which is safe in the result buffer. */ + const char *endp = result + size - 1; + char *rp; + int length; + char base[PATH_MAX+1]; + + getcwd(base, PATH_MAX); + + if(*path == '/') { + if(strlen(path) >= size) { + goto erange; + } + strcpy(result, path); + goto finish; + } else if(*base != '/' || !size) { + errno = EINVAL; + return (NULL); + } else if(size == 1) { + goto erange; + } + + length = strlen(base); + + if(!strcmp(path, ".") || !strcmp(path, "./")) { + if(length >= size) { + goto erange; + } + strcpy(result, base); + /* rp points the last char. */ + rp = result + length - 1; + /* remove the last '/'. */ + if(*rp == '/') { + if(length > 1) { + *rp = 0; + } + } else { + rp++; + } + /* rp point NULL char */ + if(*++path == '/') { + /* Append '/' to the tail of path name. */ + *rp++ = '/'; + if(rp > endp) { + goto erange; + } + *rp = 0; + } + goto finish; + } + bp = base + length; + if(*(bp - 1) == '/') { + --bp; + } + /* up to root. */ + for(pp = path; *pp && *pp == '.'; ) { + if(!strncmp(pp, "../", 3)) { + pp += 3; + while(bp > base && *--bp != '/'); + } else if(!strncmp(pp, "./", 2)) { + pp += 2; + } else if(!strncmp(pp, "..\0", 3)) { + pp += 2; + while(bp > base && *--bp != '/'); + } else { + break; + } + } + /* down to leaf. */ + length = bp - base; + if(length >= size) { + goto erange; + } + strncpy(result, base, length); + rp = result + length; + if(*pp || *(pp - 1) == '/' || length == 0) { + *rp++ = '/'; + } + if(rp + strlen(pp) > endp) { + goto erange; + } + strcpy(rp, pp); +finish: + return result; +erange: + errno = ERANGE; + return (NULL); +} + /* output a string, but wrap words properly with a specified indentation */ void indentprint(char *str, int indent) diff --git a/src/util.h b/src/util.h index 2d711391..a536c2e1 100644 --- a/src/util.h +++ b/src/util.h @@ -34,6 +34,7 @@ int unpack(char *archive, const char *prefix, const char *fn); int copyfile(char *src, char *dest); int makepath(char *path); int rmrf(char *path); +char *rel2abs(const char *path, char *result, const size_t size); void indentprint(char *str, int indent); char* trim(char *str); char* strtoupper(char *str); -- cgit v1.2.3-24-g4f1b