summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJudd Vinet <judd@archlinux.org>2004-09-18 20:37:34 +0200
committerJudd Vinet <judd@archlinux.org>2004-09-18 20:37:34 +0200
commit4ffc53b3398ae845183f991a56207459256cc9e9 (patch)
treef71a9fa0c0ab1bc87dd84cf07828fe95efbb849f
parentafc0d9a3c45b70edd948ce0be4a5e81d4da00c7e (diff)
downloadpacman-4ffc53b3398ae845183f991a56207459256cc9e9.tar.gz
pacman-4ffc53b3398ae845183f991a56207459256cc9e9.tar.xz
Imported from pacman-2.9.tar.gz
-rw-r--r--ChangeLog14
-rw-r--r--Makefile.in2
-rw-r--r--doc/pacman.8.in50
-rw-r--r--etc/pacman.conf2
-rwxr-xr-xscripts/gensync48
-rwxr-xr-xscripts/makepkg18
-rwxr-xr-xscripts/makeworld2
-rwxr-xr-xscripts/updatesync20
-rw-r--r--src/db.c23
-rw-r--r--src/list.c17
-rw-r--r--src/list.h3
-rw-r--r--src/package.c28
-rw-r--r--src/package.h5
-rw-r--r--src/pacman.c341
-rw-r--r--src/pacman.h7
-rw-r--r--src/util.c1
16 files changed, 354 insertions, 227 deletions
diff --git a/ChangeLog b/ChangeLog
index 71d69b6b..ad237530 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
VERSION DESCRIPTION
-----------------------------------------------------------------------------
+2.9 - Improved -Rs functionality -- pacman now tracks why a package
+ is installed: explicitly, or as a dependency for another
+ package. -Rs will only remove dependencies that were not
+ explicitly installed.
+ - Added compressed package size to sync DBs -- shows the total
+ size of packages before downloading
+ - Patch from Tommi Rantala:
+ - Allow --info and --list together in queries
+ - Patch from Kevin Piche:
+ - Use list_add_sorted() with -Sg
+ - Patch from Hegedus Marton Csaba:
+ - Better manpage compression
+ - Added checks for additional hyphens in package versions
+ - mktemp was failing if %pmo_root%/tmp was missing -- fixed
2.8.4 - Added updatesync script from Jason Chu
- Changed the pacman binary to be dynamically linked
- Included a pacman.static binary as well
diff --git a/Makefile.in b/Makefile.in
index d187db42..676f0742 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.8.4
+PACVER = 2.9
TOPDIR = @srcdir@
SRCDIR = $(TOPDIR)/src/
diff --git a/doc/pacman.8.in b/doc/pacman.8.in
index 1d9c9227..815cf6a6 100644
--- a/doc/pacman.8.in
+++ b/doc/pacman.8.in
@@ -1,4 +1,4 @@
-.TH pacman 8 "August 3, 2004" "pacman #VERSION#" ""
+.TH pacman 8 "September 17, 2004" "pacman #VERSION#" ""
.SH NAME
pacman \- package manager utility
.SH SYNOPSIS
@@ -53,11 +53,6 @@ Display syntax for the given operation. If no operation was
supplied then the general syntax is shown.
.SH OPTIONS
.TP
-.B "\-c, \-\-cascade"
-(only used with \fB--remove\fP)
-Remove all target packages, as well as all packages that depend on one
-or more target packages. This operation is recursive.
-.TP
.B "\-d, \-\-nodeps"
Skips all dependency checks. Normally, pacman will always check
a package's dependency fields to ensure that all dependencies are
@@ -70,17 +65,6 @@ package that is about to be installed contains files that are already
installed, this option will cause all those files to be overwritten.
This option should be used with care, ideally not at all.
.TP
-.B "\-k, \-\-keep"
-Removes the database entry only. Leaves all files in place.
-.TP
-.B "\-n, \-\-nosave"
-(only used with \fB--remove\fP)
-Instructs pacman to ignore file backup designations. Normally, when
-a file is about to be \fIremoved\fP from the system the database is first
-checked to see if the file should be renamed to a .pacsave extension. If
-\fB--nosave\fP is used, these designations are ignored and the files are
-removed.
-.TP
.B "\-r, \-\-root <path>"
Specify alternative installation root (default is "/"). This
should \fInot\fP be used as a way to install software into
@@ -90,12 +74,6 @@ which is "owned" by another system. By using this option you not only
specify where the software should be installed, but you also
specify which package database to use.
.TP
-.B "\-s, \-\-recursive"
-(only used with \fB--remove\fP)
-For each target specified, remove it and all its dependencies, provided
-they are not required by other packages. This option is analagous to
-a backwards --sync operation.
-.TP
.B "\-v, \-\-verbose"
Output more status and error messages.
.TP
@@ -151,8 +129,34 @@ Retrieve all packages from the server, but do not install/upgrade anything.
Download a fresh copy of the master package list from the ftp server
defined in \fI/etc/pacman.conf\fP. This should typically be used each
time you use \fB--sysupgrade\fP.
+.SH REMOVE OPTIONS
+.TP
+.B "\-c, \-\-cascade"
+Remove all target packages, as well as all packages that depend on one
+or more target packages. This operation is recursive.
+.TP
+.B "\-k, \-\-keep"
+Removes the database entry only. Leaves all files in place.
+.TP
+.B "\-n, \-\-nosave"
+Instructs pacman to ignore file backup designations. Normally, when
+a file is about to be \fIremoved\fP from the system the database is first
+checked to see if the file should be renamed to a .pacsave extension. If
+\fB--nosave\fP is used, these designations are ignored and the files are
+removed.
+.TP
+.B "\-s, \-\-recursive"
+For each target specified, remove it and all its dependencies, provided
+that (A) they are not required by other packages; and (B) they were
+explicitly installed by the user and not pulled in as a dependency for
+other packages. This option is analagous to a backwards --sync operation.
.SH QUERY OPTIONS
.TP
+.B "\-e, \-\-orphans"
+List all packages that were explicitly installed (ie, not pulled in
+as a dependency by other packages) and are not required by any other
+packages.
+.TP
.B "\-g, \-\-groups"
Display all groups that a specified package is part of. If no package
names are provided, all groups and members will be listed.
diff --git a/etc/pacman.conf b/etc/pacman.conf
index 21519138..7711f440 100644
--- a/etc/pacman.conf
+++ b/etc/pacman.conf
@@ -18,7 +18,7 @@
#
[options]
LogFile = /var/log/pacman.log
-NoUpgrade = etc/passwd etc/group etc/shadow
+NoUpgrade = etc/passwd etc/group etc/shadow etc/sudoers
NoUpgrade = etc/fstab etc/raidtab etc/ld.so.conf
NoUpgrade = etc/rc.conf etc/rc.local
NoUpgrade = etc/modprobe.conf etc/modules.conf
diff --git a/scripts/gensync b/scripts/gensync
index bdadc30b..8dbe8921 100755
--- a/scripts/gensync
+++ b/scripts/gensync
@@ -20,7 +20,7 @@
# USA.
#
-myver='2.8.4'
+myver='2.9'
usage() {
echo "gensync $myver"
@@ -45,9 +45,14 @@ usage() {
exit 0
}
+die() {
+ echo "gensync: $*" >&2
+ rm -rf $gstmpdir
+ exit 1
+}
+
get_md5checksum()
{
- source $1 || return 1
if [ "$pkgdir" != "" ]; then
pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
else
@@ -80,6 +85,9 @@ db_write_entry()
echo "%DESC%" >>desc
echo "$pkgdesc" >>desc
echo "" >>desc
+ echo "%CSIZE%" >>desc
+ echo "$csize" >>desc
+ echo "" >>desc
if [ ! -z $pkgmd5sum ]; then
echo "%MD5SUM%" >>desc
echo "$pkgmd5sum" >>desc
@@ -147,40 +155,30 @@ pkgdir=
if [ "$3" != "" ]; then
pkgdir=$3
fi
-gstmpdir=$(mktemp -dt gensync.XXXXXXXXXX) || exit 1
-
-if [ ! -d $rootdir ]; then
- echo "gensync: invalid root dir: $rootdir" >&2
- rm -rf $gstmpdir
- exit 1
-fi
+gstmpdir=$(mktemp -d /tmp/gensync.XXXXXXXXXX) || exit 1
+[ ! -d $rootdir ] && die "invalid root dir: $rootdir"
echo "gensync: building database entries, generating md5sums..." >&2
cd `dirname $2`
for file in `find $rootdir/* -name PKGBUILD`; do
- pkgmd5sum=`get_md5checksum $file $pkgdir`
- if [ -z $pkgmd5sum ]; then
- echo "gensync: error generating checksum for $file" >&2
- rm -rf $gstmpdir
- exit 1
+ source $file || die "errors parsing $file"
+ if [ "$pkgdir" != "" ]; then
+ pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
+ else
+ pkgfile="$destdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
fi
+ [ -f $pkgfile ] || die "missing package file: $pkgfile"
+ csize=`du -b $pkgfile | cut -f1`
+ pkgmd5sum=`get_md5checksum $pkgfile`
+ [ -z $pkgmd5sum ] && die "error generating checksum for $pkgfile"
db_write_entry $file
- if [ $? -gt 0 ]; then
- echo "gensync: error writing entry for $file" >&2
- rm -rf $gstmpdir
- exit 1
- fi
+ [ $? -gt 0 ] && die "error writing entry for $file"
done
echo "gensync: compressing to $destfile..." >&2
cd $gstmpdir
tar c * | gzip -9 >$destfile
-if [ $? -gt 0 ]; then
- echo "gensync: error writing to $destfile" >&2
- rm -rf $gstmpdir
- exit 1
-fi
+[ $? -gt 0 ] && die "error writing to $destfile"
rm -rf $gstmpdir
-
exit 0
diff --git a/scripts/makepkg b/scripts/makepkg
index 8f4103e5..98e2acc3 100755
--- a/scripts/makepkg
+++ b/scripts/makepkg
@@ -20,7 +20,7 @@
# USA.
#
-myver='2.8.4'
+myver='2.9'
startdir=`pwd`
PKGDEST=$startdir
USE_COLOR="n"
@@ -576,17 +576,17 @@ fi
# compress man pages
msg "Compressing man pages..."
-for i in `find pkg/{usr{,/local},opt/*}/man -type f 2>/dev/null`; do
- ext=${i##*.}
- fn=${i##*/}
- if [ "$ext" != "gz" ]; then
+find $startdir/pkg/{usr{,/local,/share},opt/*}/man -type f 2>/dev/null | while read i ; do
+ ext="${i##*.}"
+ fn="${i##*/}"
+ if [ "$ext" != "gz" -a "$ext" != "bz2" ]; then
# update symlinks to this manpage
- for ln in `find pkg/{usr{,/local},opt/*}/man -lname "$fn" 2>/dev/null`; do
- rm -f $ln
- ln -sf ${fn}.gz ${ln}.gz
+ find $startdir/pkg/{usr{,/local,/share},opt/*}/man -lname "$fn" 2> /dev/null | while read ln ; do
+ rm -f "$ln"
+ ln -sf "${fn}.gz" "${ln}.gz"
done
# compress the original
- gzip -9 $i
+ gzip -9 "$i"
fi
done
diff --git a/scripts/makeworld b/scripts/makeworld
index 249ae813..5346a0d5 100755
--- a/scripts/makeworld
+++ b/scripts/makeworld
@@ -21,7 +21,7 @@
#
toplevel=`pwd`
-version="2.8.4"
+version="2.9"
usage() {
echo "makeworld version $version"
diff --git a/scripts/updatesync b/scripts/updatesync
index bc17addf..50dc26f0 100755
--- a/scripts/updatesync
+++ b/scripts/updatesync
@@ -21,7 +21,7 @@
# USA.
#
-myver='2.8.4'
+myver='2.9'
usage() {
echo "updatesync $myver"
@@ -56,7 +56,6 @@ die()
get_md5checksum()
{
- source $1 || return 1
if [ "$pkgdir" != "" ]; then
pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
else
@@ -89,6 +88,9 @@ db_write_entry()
echo "%DESC%" >>desc
echo "$pkgdesc" >>desc
echo "" >>desc
+ echo "%CSIZE%" >>desc
+ echo "$csize" >>desc
+ echo "" >>desc
if [ ! -z $pkgmd5sum ]; then
echo "%MD5SUM%" >>desc
echo "$pkgmd5sum" >>desc
@@ -177,7 +179,7 @@ if [ "$action" != "upd" -a "$action" != "del" ]; then
exit 1
fi
-ustmpdir=$(mktemp -dt updatesync.XXXXXXXXXX) || exit 1
+ustmpdir=$(mktemp -d /tmp/updatesync.XXXXXXXXXX) || exit 1
cd $ustmpdir
if [ ! -f $pkgdb ]; then
@@ -202,8 +204,16 @@ if [ "$action" = "upd" ]; then
# INSERT / UPDATE
delete_entry $option
- pkgmd5sum=`get_md5checksum $option`
- [ -z $pkgmd5sum ] && die "error generating checksum for $option"
+ source $option || die "errors parsing $option"
+ if [ "$pkgdir" != "" ]; then
+ pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
+ else
+ pkgfile="$destdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
+ fi
+ [ -f $pkgfile ] || die "missing package file: $pkgfile"
+ csize=`du -b $pkgfile | cut -f1`
+ pkgmd5sum=`get_md5checksum $pkgfile`
+ [ -z $pkgmd5sum ] && die "error generating checksum for $pkgfile"
echo "updatesync: creating entry for $option" >&2
db_write_entry $option || die "error writing entry for $option"
else
diff --git a/src/db.c b/src/db.c
index 428b99e7..0faf5870 100644
--- a/src/db.c
+++ b/src/db.c
@@ -225,6 +225,14 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
return(NULL);
}
trim(info->packager);
+ } else if(!strcmp(line, "%REASON%")) {
+ char tmp[32];
+ if(fgets(tmp, sizeof(tmp), fp) == NULL) {
+ FREEPKG(info);
+ return(NULL);
+ }
+ trim(tmp);
+ info->reason = (unsigned short)atoi(tmp);
} else if(!strcmp(line, "%SIZE%")) {
char tmp[32];
if(fgets(tmp, sizeof(tmp), fp) == NULL) {
@@ -232,6 +240,19 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
return(NULL);
}
trim(tmp);
+ info->size = (unsigned long)atol(tmp);
+ } else if(!strcmp(line, "%CSIZE%")) {
+ /* NOTE: the CSIZE and SIZE fields both share the "size" field
+ * in the pkginfo_t struct. This can be done b/c CSIZE
+ * is currently only used in sync databases, and SIZE is
+ * only used in local databases.
+ */
+ char tmp[32];
+ if(fgets(tmp, sizeof(tmp), fp) == NULL) {
+ FREEPKG(info);
+ return(NULL);
+ }
+ trim(tmp);
info->size = atol(tmp);
} else if(!strcmp(line, "%REPLACES%")) {
/* the REPLACES tag is special -- it only appears in sync repositories,
@@ -387,6 +408,8 @@ int db_write(pacdb_t *db, pkginfo_t *info, unsigned int inforeq)
fprintf(fp, "%s\n\n", info->packager);
fputs("%SIZE%\n", fp);
fprintf(fp, "%ld\n\n", info->size);
+ fputs("%REASON%\n", fp);
+ fprintf(fp, "%d\n\n", info->reason);
fclose(fp);
}
diff --git a/src/list.c b/src/list.c
index b07e347f..0ec43353 100644
--- a/src/list.c
+++ b/src/list.c
@@ -102,16 +102,16 @@ int list_isin(PMList *haystack, void *needle)
/* Test for existence of a string in a PMList
*/
-int is_in(char *needle, PMList *haystack)
+PMList* is_in(char *needle, PMList *haystack)
{
PMList *lp;
for(lp = haystack; lp; lp = lp->next) {
if(lp->data && !strcmp(lp->data, needle)) {
- return(1);
+ return(lp);
}
}
- return(0);
+ return(NULL);
}
/* List one is extended and returned
@@ -224,6 +224,17 @@ void list_display(const char *title, PMList *list)
}
+/* Helper function for comparing string nodes.
+ */
+int strlist_cmp(const void *s1, const void *s2)
+{
+ char *str1 = (char *)s1;
+ char *str2 = (char *)s2;
+
+ return(strcmp(str1, str2));
+}
+
+
/* Add items to a list in sorted order. Use the given
* comparision func to determine order.
*/
diff --git a/src/list.h b/src/list.h
index 5d330fe1..655ffc7d 100644
--- a/src/list.h
+++ b/src/list.h
@@ -40,13 +40,14 @@ void list_free(PMList* list);
PMList* list_add(PMList* list, void* data);
int list_count(PMList* list);
int list_isin(PMList *haystack, void *needle);
-int is_in(char *needle, PMList *haystack);
+PMList* is_in(char *needle, PMList *haystack);
PMList* list_merge(PMList *one, PMList *two);
PMList* list_last(PMList* list);
int list_strcmp(const void *s1, const void *s2);
PMList *list_sort(PMList *list);
void list_display(const char *title, PMList *list);
+int strlist_cmp(const void *s1, const void *s2);
PMList* list_add_sorted(PMList *list, void *data, cmp_fn sortfunc);
#endif
diff --git a/src/package.c b/src/package.c
index 992110b9..ada6f411 100644
--- a/src/package.c
+++ b/src/package.c
@@ -250,6 +250,7 @@ pkginfo_t* newpkg()
pkg->size = 0;
pkg->scriptlet = 0;
pkg->force = 0;
+ pkg->reason = REASON_EXPLICIT;
pkg->requiredby = NULL;
pkg->conflicts = NULL;
pkg->files = NULL;
@@ -340,6 +341,12 @@ void dump_pkg_full(pkginfo_t *info)
printf("Build Date : %s %s\n", info->builddate, strlen(info->builddate) ? "UTC" : "");
printf("Install Date : %s %s\n", info->installdate, strlen(info->installdate) ? "UTC" : "");
printf("Install Script : %s\n", (info->scriptlet ? "Yes" : "No"));
+ printf("Reason: : ");
+ switch(info->reason) {
+ case REASON_EXPLICIT: printf("explicitly installed\n"); break;
+ case REASON_DEPEND: printf("installed as a dependency for another package\n"); break;
+ default: printf("unknown\n"); break;
+ }
pm = list_sort(info->provides);
list_display("Provides :", pm);
FREELIST(pm);
@@ -367,26 +374,27 @@ void dump_pkg_sync(pkginfo_t *info)
return;
}
- printf("Name : %s\n", info->name);
- printf("Version : %s\n", info->version);
+ printf("Name : %s\n", info->name);
+ printf("Version : %s\n", info->version);
pm = list_sort(info->groups);
- list_display("Groups :", pm);
+ list_display("Groups :", pm);
FREELIST(pm);
pm = list_sort(info->provides);
- list_display("Provides :", pm);
+ list_display("Provides :", pm);
FREELIST(pm);
pm = list_sort(info->depends);
- list_display("Depends On :", pm);
+ list_display("Depends On :", pm);
FREELIST(pm);
pm = list_sort(info->conflicts);
- list_display("Conflicts With :", pm);
+ list_display("Conflicts With :", pm);
FREELIST(pm);
pm = list_sort(info->replaces);
- list_display("Replaces :", pm);
+ list_display("Replaces :", pm);
FREELIST(pm);
- printf("Description : ");
- indentprint(info->desc, 17);
- printf("\nMD5 Sum : %s\n", info->md5sum);
+ printf("Size (compressed) : %ld\n", info->size);
+ printf("Description : ");
+ indentprint(info->desc, 20);
+ printf("\nMD5 Sum : %s\n", info->md5sum);
}
int split_pkgname(char *pkgfile, char *name, char *version)
diff --git a/src/package.h b/src/package.h
index 58ef93da..ea9a3248 100644
--- a/src/package.h
+++ b/src/package.h
@@ -33,6 +33,10 @@
FREELIST(p);\
}
+/* reasons -- ie, why the package was installed */
+#define REASON_EXPLICIT 0 /* explicitly requested by the user */
+#define REASON_DEPEND 1 /* installed as a dependency for another package */
+
/* mods for depend_t.mod */
#define DEP_ANY 0
#define DEP_EQ 1
@@ -55,6 +59,7 @@ typedef struct __pkginfo_t {
unsigned long size;
unsigned short scriptlet;
unsigned short force;
+ unsigned short reason;
PMList *replaces;
PMList *groups;
PMList *files;
diff --git a/src/pacman.c b/src/pacman.c
index df0c7454..0e7e83c8 100644
--- a/src/pacman.c
+++ b/src/pacman.c
@@ -235,12 +235,12 @@ int main(int argc, char *argv[])
/* start the requested operation */
switch(pmo_op) {
- case PM_ADD: ret = pacman_add(db_local, pm_targets); break;
- case PM_REMOVE: ret = pacman_remove(db_local, pm_targets); break;
- case PM_UPGRADE: ret = pacman_upgrade(db_local, pm_targets); break;
- case PM_QUERY: ret = pacman_query(db_local, pm_targets); break;
- case PM_SYNC: ret = pacman_sync(db_local, pm_targets); break;
- case PM_DEPTEST: ret = pacman_deptest(db_local, pm_targets); break;
+ 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_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;
+ case PM_DEPTEST: ret = pacman_deptest(db_local, pm_targets); break;
case PM_MAIN: ret = 0; break;
default: fprintf(stderr, "error: no operation specified (use -h for help)\n\n");
ret = 1;
@@ -484,20 +484,19 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
} else if(pmo_group) {
PMList *pm, *allgroups, *groups;
- i = NULL;
+ allgroups = NULL;
/* fetch the list of existing groups */
for(j = databases; j; j = j->next) {
dbsync_t *dbs = (dbsync_t*)j->data;
k = find_groups(dbs->db);
for(pm = k; pm; pm = pm->next) {
- if(!is_in((char *)pm->data, i)) {
- i = list_add(i, strdup((char *)pm->data));
+ if(!is_in((char *)pm->data, allgroups)) {
+ allgroups = list_add_sorted(allgroups, strdup((char *)pm->data),
+ strlist_cmp);
}
}
FREELIST(k);
}
- allgroups = list_sort(i);
- FREELIST(i);
if(targets) {
groups = NULL;
for(j = targets; j; j = j->next) {
@@ -705,6 +704,8 @@ int pacman_sync(pacdb_t *db, PMList *targets)
/* re-fetch the package record with dependency info */
sync->pkg = db_scan(sync->dbs->db, sync->pkg->name, INFRQ_DESC | INFRQ_DEPENDS);
+ /* copy over the install reason */
+ sync->pkg->reason = local->reason;
/* add to the targets list */
found = (find_pkginsync(sync->pkg->name, final) != NULL);
@@ -779,6 +780,8 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(sync->pkg == NULL) {
found = 0;
}
+ /* this package was explicitly requested */
+ sync->pkg->reason = REASON_EXPLICIT;
}
}
}
@@ -1051,6 +1054,8 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(final && final->data && allgood && !pmo_s_printuris) {
PMList *list = NULL;
char *str;
+ unsigned long totalsize = 0;
+ double mb;
for(i = rmtargs; i; i = i->next) {
list = list_add(list, strdup(i->data));
}
@@ -1076,12 +1081,14 @@ int pacman_sync(pacdb_t *db, PMList *targets)
MALLOC(str, strlen(s->pkg->name)+strlen(s->pkg->version)+2);
sprintf(str, "%s-%s", s->pkg->name, s->pkg->version);
list = list_add(list, str);
+ totalsize += s->pkg->size;
}
}
+ mb = (double)(totalsize / 1048576.0);
printf("\nTargets: ");
str = buildstring(list);
indentprint(str, 9);
- printf("\n");
+ printf("\n\nTotal Package Size: %.1f MB\n", mb);
FREELIST(list);
FREE(str);
}
@@ -1178,14 +1185,11 @@ int pacman_sync(pacdb_t *db, PMList *targets)
fflush(stdout);
if(stat(ldir, &buf)) {
mode_t oldmask;
- char parent[PATH_MAX];
/* no cache directory.... try creating it */
- snprintf(parent, PATH_MAX, "%svar/cache/pacman", pmo_root);
logaction(stderr, "warning: no %s cache exists. creating...", ldir);
oldmask = umask(0000);
- mkdir(parent, 0755);
- if(mkdir(ldir, 0755)) {
+ if(makepath(ldir)) {
/* couldn't mkdir the cache directory, so fall back to /tmp and unlink
* the package afterwards.
*/
@@ -1295,6 +1299,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
if(!pmo_s_downloadonly && allgood) {
+ PMList *dependonly = NULL;
/* remove any conflicting packages (WITHOUT dep checks) */
if(rmtargs) {
int retcode;
@@ -1320,6 +1325,9 @@ int pacman_sync(pacdb_t *db, PMList *targets)
MALLOC(str, PATH_MAX);
snprintf(str, PATH_MAX, "%s/%s-%s.pkg.tar.gz", ldir, sync->pkg->name, sync->pkg->version);
files = list_add(files, str);
+ if(sync->pkg->reason == REASON_DEPEND) {
+ dependonly = list_add(dependonly, strdup(str));
+ }
}
for(j = sync->replaces; j; j = j->next) {
pkginfo_t *pkg = (pkginfo_t*)j->data;
@@ -1339,7 +1347,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
/* install targets */
if(allgood) {
- allgood = !pacman_upgrade(db, files);
+ allgood = !pacman_upgrade(db, files, dependonly);
}
/* propagate replaced packages' requiredby fields to their new owners */
if(allgood) {
@@ -1413,7 +1421,7 @@ sync_cleanup:
return(!allgood);
}
-int pacman_add(pacdb_t *db, PMList *targets)
+int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
{
int i, ret = 0, errors = 0;
TAR *tar = NULL;
@@ -1435,6 +1443,10 @@ int pacman_add(pacdb_t *db, PMList *targets)
if(targets == NULL) {
return(0);
}
+ /*
+ * Check for URL targets and process them
+ *
+ */
for(targ = targets; targ; targ = targ->next) {
if(strstr(targ->data, "://")) {
/* this target looks like an URL. download it and then
@@ -1485,6 +1497,10 @@ int pacman_add(pacdb_t *db, PMList *targets)
}
}
+ /*
+ * Load meta-data from package files
+ *
+ */
printf("loading package data... ");
fflush(stdout);
for(targ = targets; targ; targ = targ->next) {
@@ -1494,6 +1510,12 @@ int pacman_add(pacdb_t *db, PMList *targets)
if(info == NULL) {
return(1);
}
+ /* no additional hyphens in version strings */
+ if(strchr(info->version, '-') != strrchr(info->version, '-')) {
+ fprintf(stderr, "\nerror: package \"%s\" has more than one hyphen in its version (%s)\n",
+ info->name, info->version);
+ return(1);
+ }
if(pmo_freshen) {
/* only upgrade/install this package if it is already installed and at a lesser version */
pkginfo_t *dummy = db_scan(db, info->name, INFRQ_DESC);
@@ -1525,6 +1547,11 @@ int pacman_add(pacdb_t *db, PMList *targets)
}
printf("done.\n");
+ /*
+ * Check dependencies
+ *
+ */
+
/* No need to check deps if pacman_add was called during a sync:
* it is already done in pacman_sync. */
if(!pmo_nodeps && pmo_op != PM_SYNC) {
@@ -1636,6 +1663,10 @@ int pacman_add(pacdb_t *db, PMList *targets)
alltargs = lp;
}
+ /*
+ * Check for file conflicts
+ *
+ */
if(!pmo_force) {
printf("checking for file conflicts... ");
fflush(stdout);
@@ -1657,6 +1688,10 @@ int pacman_add(pacdb_t *db, PMList *targets)
/* this can get modified in the next for loop, so we reset it on each iteration */
real_pmo_upgrade = pmo_upgrade;
+ /*
+ * Install packages
+ *
+ */
for(targ = alltargs, file = filenames; targ && file; targ = targ->next, file = file->next) {
pkginfo_t* oldpkg = NULL;
info = (pkginfo_t*)targ->data;
@@ -1682,33 +1717,13 @@ int pacman_add(pacdb_t *db, PMList *targets)
/* pre_upgrade scriptlet */
if(info->scriptlet) {
- char tmpdir[PATH_MAX];
- char *rtmpdir;
- snprintf(tmpdir, PATH_MAX, "%stmp/pacman-XXXXXX", pmo_root);
- if(mkdtemp(tmpdir) == NULL) {
- perror("error creating temp directory");
- return(1);
- }
- /* chop off the pmo_root so we can find the tmpdir in the chroot */
- rtmpdir = tmpdir + strlen(pmo_root) - 1;
- unpack(file->data, tmpdir, ".INSTALL");
- /* run the post-install script if it exists */
- snprintf(pm_install, PATH_MAX, "%s/.INSTALL", tmpdir);
- if(grep(pm_install, "pre_upgrade")) {
- char cmdline[PATH_MAX+1];
- snprintf(pm_install, PATH_MAX, "%s/.INSTALL", rtmpdir);
- vprint("Executing pre-upgrade script...\n");
- snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s pre_upgrade %s %s\" | chroot %s /bin/sh",
- pm_install, info->version, (oldpkg ? oldpkg->version : ""), pmo_root);
- system(cmdline);
- }
- if(rmrf(tmpdir)) {
- fprintf(stderr, "warning: could not remove tmpdir %s\n", tmpdir);
- }
+ runscriptlet(file->data, "pre_upgrade", info->version, oldpkg ? oldpkg->version : NULL);
}
if(oldpkg) {
PMList* tmp = list_add(NULL, strdup(info->name));
+ /* copy over the install reason */
+ info->reason = oldpkg->reason;
vprint("removing old package first...\n");
retcode = pacman_remove(db, tmp);
FREELIST(tmp);
@@ -1727,34 +1742,13 @@ int pacman_add(pacdb_t *db, PMList *targets)
pmo_upgrade = 0;
}
}
+
if(!pmo_upgrade) {
printf("installing %s... ", info->name);
neednl = 1;
/* pre_install scriptlet */
if(info->scriptlet) {
- char tmpdir[PATH_MAX];
- char *rtmpdir;
- snprintf(tmpdir, PATH_MAX, "%stmp/pacman-XXXXXX", pmo_root);
- if(mkdtemp(tmpdir) == NULL) {
- perror("error creating temp directory");
- return(1);
- }
- /* chop off the pmo_root so we can find the tmpdir in the chroot */
- rtmpdir = tmpdir + strlen(pmo_root) - 1;
- unpack(file->data, tmpdir, ".INSTALL");
- /* run the post-install script if it exists */
- snprintf(pm_install, PATH_MAX, "%s/.INSTALL", tmpdir);
- if(grep(pm_install, "pre_install")) {
- char cmdline[PATH_MAX+1];
- snprintf(pm_install, PATH_MAX, "%s/.INSTALL", rtmpdir);
- vprint("Executing pre-install script...\n");
- snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s pre_install %s\" | chroot %s /bin/sh",
- pm_install, info->version, pmo_root);
- system(cmdline);
- }
- if(rmrf(tmpdir)) {
- fprintf(stderr, "warning: could not remove tmpdir %s\n", tmpdir);
- }
+ runscriptlet(file->data, "pre_install", info->version, NULL);
}
}
fflush(stdout);
@@ -1792,7 +1786,7 @@ int pacman_add(pacdb_t *db, PMList *targets)
notouch = 1;
} else {
if(!pmo_upgrade || oldpkg == NULL) {
- nb = is_in(pathname, info->backup);
+ nb = is_in(pathname, info->backup) ? 1 : 0;
} else {
/* op == PM_UPGRADE */
md5_orig = needbackup(pathname, oldpkg->backup);
@@ -1976,6 +1970,13 @@ int pacman_add(pacdb_t *db, PMList *targets)
}
vprint("Updating database...");
+ /* Figure out whether this package was installed explicitly by the user
+ * or installed as a dependency for another package
+ */
+ info->reason = REASON_EXPLICIT;
+ if(is_in(file->data, dependonly)) {
+ info->reason = REASON_DEPEND;
+ }
/* make an install date (in UTC) */
strncpy(info->installdate, asctime(gmtime(&t)), sizeof(info->installdate));
if(db_write(db, info, INFRQ_ALL)) {
@@ -2019,16 +2020,12 @@ int pacman_add(pacdb_t *db, PMList *targets)
}
printf("done.\n"); fflush(stdout);
- /* run the post-install script if it exists */
+ /* run the post-install/upgrade script if it exists */
snprintf(pm_install, PATH_MAX, "%s%s/%s/%s-%s/install", pmo_root, pmo_dbpath, db->treename, info->name, info->version);
- if(!stat(pm_install, &buf) && (grep(pm_install, "post_install") || grep(pm_install, "post_upgrade"))) {
- char cmdline[PATH_MAX+1];
- snprintf(pm_install, PATH_MAX, "%s/%s/%s-%s/install", pmo_dbpath, db->treename, info->name, info->version);
- vprint("Executing post-install script...\n");
- snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s post_%s %s %s\" | chroot %s /bin/sh",
- pm_install, (pmo_upgrade ? "upgrade" : "install"), info->version,
- ((pmo_upgrade && oldpkg) ? oldpkg->version : ""), pmo_root);
- system(cmdline);
+ if(pmo_upgrade) {
+ runscriptlet(pm_install, "post_upgrade", info->version, oldpkg ? oldpkg->version : NULL);
+ } else {
+ runscriptlet(pm_install, "post_install", info->version, NULL);
}
}
@@ -2170,16 +2167,9 @@ int pacman_remove(pacdb_t *db, PMList *targets)
printf("removing %s... ", info->name);
neednl = 1;
fflush(stdout);
- /* run the pre-remove script if it exists */
+ /* run the pre-remove scriptlet if it exists */
snprintf(pm_install, PATH_MAX, "%s%s/%s/%s-%s/install", pmo_root, pmo_dbpath, db->treename, info->name, info->version);
- if(!stat(pm_install, &buf) && grep(pm_install, "pre_remove")) {
- vprint("Executing pre-remove script...\n");
- snprintf(pm_install, PATH_MAX, "%s/%s/%s-%s/install", pmo_dbpath, db->treename, info->name, info->version);
- snprintf(line, PATH_MAX, "echo \"umask 0022; source %s pre_remove %s\" | chroot %s /bin/sh",
- pm_install, info->version, pmo_root);
-
- system(line);
- }
+ runscriptlet(pm_install, "pre_remove", info->version, NULL);
}
if(!pmo_r_dbonly) {
@@ -2236,14 +2226,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
if(!pmo_upgrade) {
/* run the post-remove script if it exists */
snprintf(pm_install, PATH_MAX, "%s%s/%s/%s-%s/install", pmo_root, pmo_dbpath, db->treename, info->name, info->version);
- if(!stat(pm_install, &buf) && grep(pm_install, "post_remove")) {
- vprint("Executing post-remove script...\n");
- snprintf(pm_install, PATH_MAX, "%s/%s/%s-%s/install", pmo_dbpath, db->treename, info->name, info->version);
- snprintf(line, PATH_MAX, "echo \"umask 0022; source %s post_remove %s\" | chroot %s /bin/sh",
- pm_install, info->version, pmo_root);
-
- system(line);
- }
+ runscriptlet(pm_install, "post_remove", info->version, NULL);
}
/* remove the package from the database */
@@ -2398,11 +2381,13 @@ int pacman_query(pacdb_t *db, PMList *targets)
if(pmo_q_info) {
dump_pkg_full(info);
printf("\n");
- } else if(pmo_q_list) {
+ }
+ if(pmo_q_list) {
for(lp = info->files; lp; lp = lp->next) {
printf("%s %s\n", info->name, (char*)lp->data);
}
- } else {
+ }
+ if (!pmo_q_info && !pmo_q_list) {
printf("%s %s\n", info->name, info->version);
}
FREEPKG(info);
@@ -2444,23 +2429,21 @@ int pacman_query(pacdb_t *db, PMList *targets)
/* no target */
for(lp = pm_packages; lp; lp = lp->next) {
pkginfo_t *tmpp = (pkginfo_t*)lp->data;
- if(pmo_q_list) {
- info = db_scan(db, tmpp->name, INFRQ_DESC | INFRQ_FILES);
+ if(pmo_q_list || pmo_q_orphans) {
+ info = db_scan(db, tmpp->name, INFRQ_ALL);
if(info == NULL) {
/* something weird happened */
return(1);
}
- for(q = info->files; q; q = q->next) {
- printf("%s %s%s\n", info->name, pmo_root, (char*)q->data);
- }
- FREEPKG(info);
- } else if(pmo_q_orphans) {
- info = db_scan(db, tmpp->name, INFRQ_DESC | INFRQ_DEPENDS);
- if(info == NULL) {
- return(1);
+ if(pmo_q_list) {
+ for(q = info->files; q; q = q->next) {
+ printf("%s %s%s\n", info->name, pmo_root, (char*)q->data);
+ }
}
- if(info->requiredby == NULL) {
- printf("%s %s\n", tmpp->name, tmpp->version);
+ if(pmo_q_orphans) {
+ if(info->requiredby == NULL && info->reason == REASON_EXPLICIT) {
+ printf("%s %s\n", tmpp->name, tmpp->version);
+ }
}
FREEPKG(info);
} else {
@@ -2469,55 +2452,53 @@ int pacman_query(pacdb_t *db, PMList *targets)
}
} else {
/* find a target */
- if(pmo_q_info) {
+ if(pmo_q_info || pmo_q_list) {
info = db_scan(db, package, INFRQ_ALL);
if(info == NULL) {
fprintf(stderr, "Package \"%s\" was not found.\n", package);
return(2);
}
- dump_pkg_full(info);
- if(pmo_q_info > 1 && info->backup) {
- /* extra info */
- printf("\n");
- for(lp = info->backup; lp; lp = lp->next) {
- struct stat buf;
- char path[PATH_MAX];
- char *md5sum;
- char *str = strdup(lp->data);
- char *ptr = index(str, '\t');
- if(ptr == NULL) {
- FREE(str);
- continue;
- }
- *ptr = '\0';
- ptr++;
- snprintf(path, PATH_MAX-1, "%s%s", pmo_root, str);
- if(!stat(path, &buf)) {
- md5sum = MDFile(path);
- if(md5sum == NULL) {
- fprintf(stderr, "error calculating md5sum for %s\n", path);
+ if(pmo_q_info) {
+ dump_pkg_full(info);
+ if(pmo_q_info > 1 && info->backup) {
+ /* extra info */
+ printf("\n");
+ for(lp = info->backup; lp; lp = lp->next) {
+ struct stat buf;
+ char path[PATH_MAX];
+ char *md5sum;
+ char *str = strdup(lp->data);
+ char *ptr = index(str, '\t');
+ if(ptr == NULL) {
+ FREE(str);
continue;
}
- if(strcmp(md5sum, ptr)) {
- printf("MODIFIED\t%s\n", path);
+ *ptr = '\0';
+ ptr++;
+ snprintf(path, PATH_MAX-1, "%s%s", pmo_root, str);
+ if(!stat(path, &buf)) {
+ md5sum = MDFile(path);
+ if(md5sum == NULL) {
+ fprintf(stderr, "error calculating md5sum for %s\n", path);
+ continue;
+ }
+ if(strcmp(md5sum, ptr)) {
+ printf("MODIFIED\t%s\n", path);
+ } else {
+ printf("NOT MODIFIED\t%s\n", path);
+ }
} else {
- printf("NOT MODIFIED\t%s\n", path);
+ printf("MISSING\t\t%s\n", path);
}
- } else {
- printf("MISSING\t\t%s\n", path);
+ FREE(str);
}
- FREE(str);
}
+ printf("\n");
}
- printf("\n");
- } else if(pmo_q_list) {
- info = db_scan(db, package, INFRQ_DESC | INFRQ_FILES);
- if(info == NULL) {
- fprintf(stderr, "Package \"%s\" was not found.\n", package);
- return(2);
- }
- for(lp = info->files; lp; lp = lp->next) {
- printf("%s %s%s\n", info->name, pmo_root, (char*)lp->data);
+ if(pmo_q_list) {
+ for(lp = info->files; lp; lp = lp->next) {
+ printf("%s %s%s\n", info->name, pmo_root, (char*)lp->data);
+ }
}
} else if(pmo_q_orphans) {
info = db_scan(db, package, INFRQ_DESC | INFRQ_DEPENDS);
@@ -2543,12 +2524,12 @@ int pacman_query(pacdb_t *db, PMList *targets)
return(0);
}
-int pacman_upgrade(pacdb_t *db, PMList *targets)
+int pacman_upgrade(pacdb_t *db, PMList *targets, PMList *dependonly)
{
/* this is basically just a remove-then-add process. pacman_add() will */
/* handle it */
pmo_upgrade = 1;
- return(pacman_add(db, targets));
+ return(pacman_add(db, targets, dependonly));
}
/* Re-order a list of target packages with respect to their dependencies.
@@ -2630,6 +2611,10 @@ PMList* sortbydeps(PMList *targets)
* target list, as well as all their un-needed dependencies. By un-needed,
* I mean dependencies that are *only* required for packages in the target
* list, so they can be safely removed. This function is recursive.
+ *
+ * NOTE: as of version 2.9, this will only remove packages that were
+ * not explicitly installed (ie, reason == REASON_DEPEND)
+ *
*/
PMList* removedeps(pacdb_t *db, PMList *targs)
{
@@ -2663,6 +2648,11 @@ PMList* removedeps(pacdb_t *db, PMList *targs)
if(is_pkgin(dep, targs)) {
continue;
}
+ /* see if it was explicitly installed */
+ if(dep->reason == REASON_EXPLICIT) {
+ vprint("excluding %s -- explicitly installed\n", dep->name);
+ needed = 1;
+ }
/* see if other packages need it */
for(k = dep->requiredby; k && !needed; k = k->next) {
pkginfo_t *dummy;
@@ -2726,6 +2716,7 @@ int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *syncpkg, PMList *l
found = 1;
/* re-fetch the package record with dependency info */
sync->pkg = db_scan(dbs->db, pkg->name, INFRQ_DESC | INFRQ_DEPENDS);
+ sync->pkg->reason = REASON_DEPEND;
sync->dbs = dbs;
}
}
@@ -2739,6 +2730,7 @@ int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *syncpkg, PMList *l
found = 1;
/* re-fetch the package record with dependency info */
sync->pkg = db_scan(dbs->db, provides->data, INFRQ_DESC | INFRQ_DEPENDS);
+ sync->pkg->reason = REASON_DEPEND;
sync->dbs = dbs;
}
list_free(provides);
@@ -3222,6 +3214,63 @@ char* needbackup(char* file, PMList *backup)
return(NULL);
}
+/* Executes a scriptlet.
+ */
+int runscriptlet(char *installfn, char *script, char *ver, char *oldver)
+{
+ char scriptfn[PATH_MAX];
+ char cmdline[PATH_MAX];
+ char tmpdir[PATH_MAX] = "";
+ char *scriptpath;
+ struct stat buf;
+
+ if(stat(installfn, &buf)) {
+ /* not found */
+ return(0);
+ }
+
+ if(!strcmp(script, "pre_upgrade") || !strcmp(script, "pre_install")) {
+ snprintf(tmpdir, PATH_MAX, "%stmp/", pmo_root);
+ if(stat(tmpdir, &buf)) {
+ makepath(tmpdir);
+ }
+ snprintf(tmpdir, PATH_MAX, "%stmp/pacman-XXXXXX", pmo_root);
+ if(mkdtemp(tmpdir) == NULL) {
+ perror("error creating temp directory");
+ return(1);
+ }
+ unpack(installfn, tmpdir, ".INSTALL");
+ snprintf(scriptfn, PATH_MAX, "%s/.INSTALL", tmpdir);
+ /* chop off the pmo_root so we can find the tmpdir in the chroot */
+ scriptpath = scriptfn + strlen(pmo_root) - 1;
+ } else {
+ strncpy(scriptfn, installfn, PATH_MAX-1);
+ /* chop off the pmo_root so we can find the tmpdir in the chroot */
+ scriptpath = scriptfn + strlen(pmo_root) - 1;
+ }
+
+ if(!grep(scriptfn, script)) {
+ /* script not found in scriptlet file */
+ return(0);
+ }
+
+ vprint("Executing %s script...\n", script);
+ if(oldver) {
+ snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s %s\" | 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",
+ scriptpath, script, ver, pmo_root);
+ }
+ vprint("%s\n", cmdline);
+ system(cmdline);
+
+ if(strlen(tmpdir) && rmrf(tmpdir)) {
+ fprintf(stderr, "warning: could not remove tmpdir %s\n", tmpdir);
+ }
+ return(0);
+}
+
/* Parse command-line arguments for each operation
* op: the operation code requested
* argc: argc
@@ -3615,8 +3664,10 @@ void usage(int op, char *myname)
} else if(op == PM_QUERY) {
printf("usage: %s {-Q --query} [options] [package]\n", myname);
printf("options:\n");
- printf(" -i, --info view package information (use -ii for more)\n");
+ printf(" -e, --orphans list all packages that were explicitly installed\n");
+ printf(" and are not required by any other packages\n");
printf(" -g, --groups view all members of a package group\n");
+ printf(" -i, --info view package information (use -ii for more)\n");
printf(" -l, --list list the contents of the queried package\n");
printf(" -o, --owns <file> query the package that owns <file>\n");
printf(" -p, --file pacman will query the package file [package] instead of\n");
diff --git a/src/pacman.h b/src/pacman.h
index d7f30fc3..a87f569e 100644
--- a/src/pacman.h
+++ b/src/pacman.h
@@ -22,7 +22,7 @@
#define _PAC_PACMAN_H
#ifndef PACVER
-#define PACVER "2.8.4"
+#define PACVER "2.9"
#endif
#ifndef PKGDIR
@@ -48,9 +48,9 @@
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
-int pacman_add(pacdb_t *db, PMList *targets);
+int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly);
int pacman_remove(pacdb_t *db, PMList *targets);
-int pacman_upgrade(pacdb_t *db, PMList *targets);
+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);
int pacman_deptest(pacdb_t *db, PMList *targets);
@@ -62,6 +62,7 @@ int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *sync, PMList *list
int splitdep(char *depstr, depend_t *depend);
char* needbackup(char *file, PMList *backup);
+int runscriptlet(char *installfn, char *script, char *ver, char *oldver);
int parseargs(int op, int argc, char **argv);
int parseconfig(char *configfile);
diff --git a/src/util.c b/src/util.c
index d9814210..6d3ed0fa 100644
--- a/src/util.c
+++ b/src/util.c
@@ -147,6 +147,7 @@ int makepath(char *path)
if(stat(full, &buf)) {
if(mkdir(full, 0755)) {
free(orig);
+ umask(oldmask);
return(1);
}
}