diff options
author | Judd Vinet <judd@archlinux.org> | 2005-08-20 00:41:20 +0200 |
---|---|---|
committer | Judd Vinet <judd@archlinux.org> | 2005-08-20 00:41:20 +0200 |
commit | 08962d40c076e0343af724db6243c81cff2c7c25 (patch) | |
tree | 9d14c997a01ce9f41c0f29b9a4158b71ecf6f0d4 /src | |
parent | d05f0047a02a2b3b3f1a07c0feb980837a3496a3 (diff) | |
download | pacman-08962d40c076e0343af724db6243c81cff2c7c25.tar.gz pacman-08962d40c076e0343af724db6243c81cff2c7c25.tar.xz |
Imported from pacman-2.9.7-TEST.tar.gz
Diffstat (limited to 'src')
-rw-r--r-- | src/db.c | 140 | ||||
-rw-r--r-- | src/md5.h | 2 | ||||
-rw-r--r-- | src/pacconf.h | 2 | ||||
-rw-r--r-- | src/package.c | 10 | ||||
-rw-r--r-- | src/package.h | 2 | ||||
-rw-r--r-- | src/pacman.c | 40 | ||||
-rw-r--r-- | src/util.c | 97 | ||||
-rw-r--r-- | src/util.h | 1 |
8 files changed, 215 insertions, 79 deletions
@@ -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); } } } @@ -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; @@ -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) @@ -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); |