summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJudd Vinet <judd@archlinux.org>2005-08-20 00:41:20 +0200
committerJudd Vinet <judd@archlinux.org>2005-08-20 00:41:20 +0200
commit08962d40c076e0343af724db6243c81cff2c7c25 (patch)
tree9d14c997a01ce9f41c0f29b9a4158b71ecf6f0d4 /src
parentd05f0047a02a2b3b3f1a07c0feb980837a3496a3 (diff)
downloadpacman-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.c140
-rw-r--r--src/md5.h2
-rw-r--r--src/pacconf.h2
-rw-r--r--src/package.c10
-rw-r--r--src/package.h2
-rw-r--r--src/pacman.c40
-rw-r--r--src/util.c97
-rw-r--r--src/util.h1
8 files changed, 215 insertions, 79 deletions
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);