summaryrefslogtreecommitdiff
path: root/pcr/pacman-color
diff options
context:
space:
mode:
authoraurelien <aurelien@cwb.io>2012-11-13 16:42:17 +0100
committeraurelien <aurelien@cwb.io>2012-11-13 16:42:17 +0100
commit5ae2d0f4bb7b2d29aca46139292207252616ac1f (patch)
tree5ddf00b36f0c80c65769409af8be6bffe7643206 /pcr/pacman-color
parent0019e0942eb838ccf7fa72962e0f0d9f49cd1cf4 (diff)
humm be
Diffstat (limited to 'pcr/pacman-color')
-rw-r--r--pcr/pacman-color/0001-Add-conflict-for-replacing-owned-empty-directory.patch152
-rw-r--r--pcr/pacman-color/0002-Check-empty-subdirectory-ownership.patch61
-rw-r--r--pcr/pacman-color/PKGBUILD42
-rw-r--r--pcr/pacman-color/color.conf46
-rw-r--r--pcr/pacman-color/pacman-color-4.0.3.patch1297
5 files changed, 1598 insertions, 0 deletions
diff --git a/pcr/pacman-color/0001-Add-conflict-for-replacing-owned-empty-directory.patch b/pcr/pacman-color/0001-Add-conflict-for-replacing-owned-empty-directory.patch
new file mode 100644
index 000000000..85622aaac
--- /dev/null
+++ b/pcr/pacman-color/0001-Add-conflict-for-replacing-owned-empty-directory.patch
@@ -0,0 +1,152 @@
+From 717fdb8ee0fd23cf72fc7d2832317f513caefa2c Mon Sep 17 00:00:00 2001
+From: Allan McRae <allan@archlinux.org>
+Date: Sun, 8 Jul 2012 21:36:36 +1000
+Subject: [PATCH 1/4] Add conflict for replacing owned empty directory
+
+When two packages own an empty directory, pacman finds no conflict when
+one of those packages wants to replace the directory with a file or a
+symlink. When it comes to actually extracting the new file/symlink,
+pacman sees the directory is still there (we do not remove empty
+directories if they are owned by a package) and refuses to extract.
+
+Detect this potential conflict early and bail. Note that it is a
+_potential_ conflict and not a guaranteed one as the other package owning
+the directory could be updated or removed first which would remove
+the conflict. However, pacman currently can not sort package installation
+order to ensure this, so this conflict requires manual upgrade ordering.
+
+Signed-off-by: Allan McRae <allan@archlinux.org>
+Signed-off-by: Dan McGee <dan@archlinux.org>
+---
+ lib/libalpm/conflict.c | 32 ++++++++++++++++++++++++++------
+ test/pacman/tests/fileconflict009.py | 20 ++++++++++++++++++++
+ test/pacman/tests/fileconflict010.py | 20 ++++++++++++++++++++
+ 3 files changed, 66 insertions(+), 6 deletions(-)
+ create mode 100644 test/pacman/tests/fileconflict009.py
+ create mode 100644 test/pacman/tests/fileconflict010.py
+
+diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
+index 32f6f30..efa1a87 100644
+--- a/lib/libalpm/conflict.c
++++ b/lib/libalpm/conflict.c
+@@ -328,15 +328,35 @@ const alpm_file_t *_alpm_filelist_contains(alpm_filelist_t *filelist,
+ return NULL;
+ }
+
+-static int dir_belongsto_pkg(const char *root, const char *dirpath,
++static int dir_belongsto_pkg(alpm_handle_t *handle, const char *dirpath,
+ alpm_pkg_t *pkg)
+ {
++ alpm_list_t *i;
+ struct stat sbuf;
+ char path[PATH_MAX];
+ char abspath[PATH_MAX];
+- struct dirent *ent = NULL;
+ DIR *dir;
++ struct dirent *ent = NULL;
++ const char *root = handle->root;
++
++ /* TODO: this is an overly strict check but currently pacman will not
++ * overwrite a directory with a file (case 10/11 in add.c). Adjusting that
++ * is not simple as even if the directory is being unowned by a conflicting
++ * package, pacman does not sort this to ensure all required directory
++ * "removals" happen before installation of file/symlink */
++
++ /* check that no other _installed_ package owns the directory */
++ for(i = _alpm_db_get_pkgcache(handle->db_local); i; i = i->next) {
++ if(pkg == i->data) {
++ continue;
++ }
++
++ if(_alpm_filelist_contains(alpm_pkg_get_files(i->data), dirpath)) {
++ return 0;
++ }
++ }
+
++ /* check all files in directory are owned by the package */
+ snprintf(abspath, PATH_MAX, "%s%s", root, dirpath);
+ dir = opendir(abspath);
+ if(dir == NULL) {
+@@ -349,13 +369,13 @@ static int dir_belongsto_pkg(const char *root, const char *dirpath,
+ if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
+ continue;
+ }
+- snprintf(path, PATH_MAX, "%s/%s", dirpath, name);
++ snprintf(path, PATH_MAX, "%s%s", dirpath, name);
+ snprintf(abspath, PATH_MAX, "%s%s", root, path);
+ if(stat(abspath, &sbuf) != 0) {
+ continue;
+ }
+ if(S_ISDIR(sbuf.st_mode)) {
+- if(dir_belongsto_pkg(root, path, pkg)) {
++ if(dir_belongsto_pkg(handle, path, pkg)) {
+ continue;
+ } else {
+ closedir(dir);
+@@ -529,9 +549,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
+ sprintf(dir, "%s/", filestr);
+ if(_alpm_filelist_contains(alpm_pkg_get_files(dbpkg), dir)) {
+ _alpm_log(handle, ALPM_LOG_DEBUG,
+- "check if all files in %s belongs to %s\n",
++ "check if all files in %s belong to %s\n",
+ dir, dbpkg->name);
+- resolved_conflict = dir_belongsto_pkg(handle->root, filestr, dbpkg);
++ resolved_conflict = dir_belongsto_pkg(handle, dir, dbpkg);
+ }
+ free(dir);
+ }
+diff --git a/test/pacman/tests/fileconflict009.py b/test/pacman/tests/fileconflict009.py
+new file mode 100644
+index 0000000..904af4a
+--- /dev/null
++++ b/test/pacman/tests/fileconflict009.py
+@@ -0,0 +1,20 @@
++self.description = "dir->symlink change during package upgrade (directory conflict)"
++
++lp1 = pmpkg("pkg1")
++lp1.files = ["dir/"]
++self.addpkg2db("local", lp1)
++
++lp2 = pmpkg("pkg2")
++lp2.files = ["dir/"]
++self.addpkg2db("local", lp2)
++
++p = pmpkg("pkg1", "1.0-2")
++p.files = ["dir -> /usr/dir"]
++self.addpkg2db("sync", p)
++
++self.args = "-S pkg1"
++
++self.addrule("PACMAN_RETCODE=1")
++self.addrule("PKG_VERSION=pkg1|1.0-1")
++self.addrule("PKG_VERSION=pkg2|1.0-1")
++self.addrule("DIR_EXIST=dir/")
+diff --git a/test/pacman/tests/fileconflict010.py b/test/pacman/tests/fileconflict010.py
+new file mode 100644
+index 0000000..0a3ce83
+--- /dev/null
++++ b/test/pacman/tests/fileconflict010.py
+@@ -0,0 +1,20 @@
++self.description = "dir->file change during package upgrade (directory conflict)"
++
++lp1 = pmpkg("pkg1")
++lp1.files = ["dir/"]
++self.addpkg2db("local", lp1)
++
++lp2 = pmpkg("pkg2")
++lp2.files = ["dir/"]
++self.addpkg2db("local", lp2)
++
++p = pmpkg("pkg1", "1.0-2")
++p.files = ["dir"]
++self.addpkg2db("sync", p)
++
++self.args = "-S pkg1"
++
++self.addrule("PACMAN_RETCODE=1")
++self.addrule("PKG_VERSION=pkg1|1.0-1")
++self.addrule("PKG_VERSION=pkg2|1.0-1")
++self.addrule("DIR_EXIST=dir/")
+--
+1.7.11.1
+
diff --git a/pcr/pacman-color/0002-Check-empty-subdirectory-ownership.patch b/pcr/pacman-color/0002-Check-empty-subdirectory-ownership.patch
new file mode 100644
index 000000000..6cf496d16
--- /dev/null
+++ b/pcr/pacman-color/0002-Check-empty-subdirectory-ownership.patch
@@ -0,0 +1,61 @@
+From 44e9fdd0e848382337edb97d41e7317638a67bac Mon Sep 17 00:00:00 2001
+From: Allan McRae <allan@archlinux.org>
+Date: Sun, 8 Jul 2012 23:58:37 +1000
+Subject: [PATCH 2/4] Check empty subdirectory ownership
+
+When checking if a package owns a directory, it is important to check
+not only that all the files in the directory are part of the package,
+but also if the directory is part of a package. This catches empty
+subdirectories during conflict checking for directory to file/symlink
+replacements.
+
+Signed-off-by: Allan McRae <allan@archlinux.org>
+Signed-off-by: Dan McGee <dan@archlinux.org>
+---
+ lib/libalpm/conflict.c | 5 +++++
+ test/pacman/tests/fileconflict012.py | 17 +++++++++++++++++
+ 2 files changed, 22 insertions(+)
+ create mode 100644 test/pacman/tests/fileconflict012.py
+
+diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
+index efa1a87..d6e5d8c 100644
+--- a/lib/libalpm/conflict.c
++++ b/lib/libalpm/conflict.c
+@@ -339,6 +339,11 @@ static int dir_belongsto_pkg(alpm_handle_t *handle, const char *dirpath,
+ struct dirent *ent = NULL;
+ const char *root = handle->root;
+
++ /* check directory is actually in package - used for subdirectory checks */
++ if(!_alpm_filelist_contains(alpm_pkg_get_files(pkg), dirpath)) {
++ return 0;
++ }
++
+ /* TODO: this is an overly strict check but currently pacman will not
+ * overwrite a directory with a file (case 10/11 in add.c). Adjusting that
+ * is not simple as even if the directory is being unowned by a conflicting
+diff --git a/test/pacman/tests/fileconflict012.py b/test/pacman/tests/fileconflict012.py
+new file mode 100644
+index 0000000..421b739
+--- /dev/null
++++ b/test/pacman/tests/fileconflict012.py
+@@ -0,0 +1,17 @@
++self.description = "dir->file change during package upgrade (filesystem file conflict)"
++
++lp1 = pmpkg("pkg1")
++lp1.files = ["dir/"]
++self.addpkg2db("local", lp1)
++
++self.filesystem = ["dir/file"]
++
++p = pmpkg("pkg1", "1.0-2")
++p.files = ["dir"]
++self.addpkg2db("sync", p)
++
++self.args = "-S pkg1"
++
++self.addrule("PACMAN_RETCODE=1")
++self.addrule("PKG_VERSION=pkg1|1.0-1")
++self.addrule("DIR_EXIST=dir/")
+--
+1.7.11.1
+
diff --git a/pcr/pacman-color/PKGBUILD b/pcr/pacman-color/PKGBUILD
new file mode 100644
index 000000000..525f965b9
--- /dev/null
+++ b/pcr/pacman-color/PKGBUILD
@@ -0,0 +1,42 @@
+# Contributor: JokerBoy <jokerboy at punctweb dot ro>
+# Contributor: vogo <vogo(at)seznam(dot)cz>
+# Maintainer : Parabola GNU / Linux-libre <aurelien@cwb.io>
+
+pkgname=pacman-color
+pkgver=4.0.3
+pkgrel=3
+pkgdesc="A color patched command-line frontend for libalpm (Pacman)"
+arch=('i686' 'x86_64')
+url="http://www.archlinux.org/pacman/"
+license=('GPL')
+depends=('pacman>=4.0' 'pacman<4.1')
+backup=('etc/pacman.d/color.conf')
+source=("http://mirrors.kernel.org/archlinux/other/pacman/pacman-${pkgver}.tar.gz"
+ '0001-Add-conflict-for-replacing-owned-empty-directory.patch'
+ '0002-Check-empty-subdirectory-ownership.patch'
+ "${pkgname}-${pkgver}.patch"
+ 'color.conf')
+md5sums=('387965c7125e60e5f0b9ff3b427fe0f9'
+ '1a9b79788640907a2b34e8671cacc94a'
+ 'a9ddd43891bed364e1e97d27b2887bf1'
+ '185e6a488b1aa14db4a54b71eb5e5e29'
+ '47665f5054196c20ba0dd280a8d4c5e1')
+
+build() {
+ cd "pacman-${pkgver}"
+ patch -p1 -i "${srcdir}/0001-Add-conflict-for-replacing-owned-empty-directory.patch"
+ patch -p1 -i "${srcdir}/0002-Check-empty-subdirectory-ownership.patch"
+ patch -p1 -i "${srcdir}/${pkgname}-${pkgver}.patch"
+ ./configure \
+ --prefix=/usr \
+ --sysconfdir=/etc \
+ --localstatedir=/var \
+ --disable-doc
+ make
+}
+
+package() {
+ # install pacman-color && color.conf
+ install -Dm755 "pacman-${pkgver}/src/pacman/.libs/pacman" "${pkgdir}/usr/bin/pacman-color"
+ install -Dm644 'color.conf' "${pkgdir}/etc/pacman.d/color.conf"
+}
diff --git a/pcr/pacman-color/color.conf b/pcr/pacman-color/color.conf
new file mode 100644
index 000000000..4978d4e62
--- /dev/null
+++ b/pcr/pacman-color/color.conf
@@ -0,0 +1,46 @@
+# Configuration for pacman-color
+# ------------------------------
+# in default are all colors "intensive",
+# it looks much better on black backround
+#
+# valid colors:
+# black
+# red
+# green
+# yellow
+# blue
+# magenta
+# cyan
+# white
+# gray
+# intensive red
+# intensive green
+# intensive yellow
+# intensive blue
+# intensive magenta
+# intensive cyan
+# intensive white
+# intensive foreground
+# none
+
+# error: prefix, fail, Remove (?):, MISSING
+#Red = intensive red
+
+# done, success, pkg version, Not Modified
+#Green = intensive green
+
+# warning: prefix, Targets (?):, MODIFIED
+#Yellow = intensive yellow
+
+# :: prefix, pkg group, counter in install proces
+#Blue = intensive blue
+
+# repo name, package file name
+#Magenta = intensive magenta
+
+# url, flag installed
+#Cyan = intensive cyan
+
+# messages with :: prefix, titles, etc
+#White = intensive foreground
+
diff --git a/pcr/pacman-color/pacman-color-4.0.3.patch b/pcr/pacman-color/pacman-color-4.0.3.patch
new file mode 100644
index 000000000..c7b52ef04
--- /dev/null
+++ b/pcr/pacman-color/pacman-color-4.0.3.patch
@@ -0,0 +1,1297 @@
+diff -up -Npaur a/src/pacman/callback.c b/src/pacman/callback.c
+--- a/src/pacman/callback.c 2012-02-03 01:19:15.000000000 +0200
++++ b/src/pacman/callback.c 2012-07-20 21:48:20.266827634 +0300
+@@ -221,16 +221,16 @@ void cb_event(alpm_event_t event, void *
+ printf(_("generating %s with %s... "), (char *)data1, (char *)data2);
+ break;
+ case ALPM_EVENT_DELTA_PATCH_DONE:
+- printf(_("success!\n"));
++ color_printf(COLOR_GREEN_ALL, _("success!\n"));
+ break;
+ case ALPM_EVENT_DELTA_PATCH_FAILED:
+- printf(_("failed.\n"));
++ color_printf(COLOR_RED_ALL, _("failed.\n"));
+ break;
+ case ALPM_EVENT_SCRIPTLET_INFO:
+ printf("%s", (char *)data1);
+ break;
+ case ALPM_EVENT_RETRIEVE_START:
+- printf(_(":: Retrieving packages from %s...\n"), (char *)data1);
++ color_printf(COLOR_DOUBLECOLON, _(":: Retrieving packages from %s...\n"), (char *)data1);
+ break;
+ case ALPM_EVENT_DISKSPACE_START:
+ if(config->noprogressbar) {
+@@ -264,14 +264,14 @@ void cb_question(alpm_question_t event,
+ switch(event) {
+ case ALPM_QUESTION_INSTALL_IGNOREPKG:
+ if(!config->op_s_downloadonly) {
+- *response = yesno(_(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"),
++ *response = yesno(COLOR_DOUBLECOLON, _(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"),
+ alpm_pkg_get_name(data1));
+ } else {
+ *response = 1;
+ }
+ break;
+ case ALPM_QUESTION_REPLACE_PKG:
+- *response = yesno(_(":: Replace %s with %s/%s?"),
++ *response = yesno(COLOR_DOUBLECOLON, _(":: Replace %s with %s/%s?"),
+ alpm_pkg_get_name(data1),
+ (char *)data3,
+ alpm_pkg_get_name(data2));
+@@ -280,12 +280,12 @@ void cb_question(alpm_question_t event,
+ /* data parameters: target package, local package, conflict (strings) */
+ /* print conflict only if it contains new information */
+ if(strcmp(data1, data3) == 0 || strcmp(data2, data3) == 0) {
+- *response = noyes(_(":: %s and %s are in conflict. Remove %s?"),
++ *response = noyes(COLOR_DOUBLECOLON, _(":: %s and %s are in conflict. Remove %s?"),
+ (char *)data1,
+ (char *)data2,
+ (char *)data2);
+ } else {
+- *response = noyes(_(":: %s and %s are in conflict (%s). Remove %s?"),
++ *response = noyes(COLOR_DOUBLECOLON, _(":: %s and %s are in conflict (%s). Remove %s?"),
+ (char *)data1,
+ (char *)data2,
+ (char *)data3,
+@@ -302,13 +302,13 @@ void cb_question(alpm_question_t event,
+ (char *)alpm_pkg_get_name(i->data));
+ count++;
+ }
+- printf(_n(
++ color_printf(COLOR_DOUBLECOLON, _n(
+ ":: The following package cannot be upgraded due to unresolvable dependencies:\n",
+ ":: The following packages cannot be upgraded due to unresolvable dependencies:\n",
+ count));
+- list_display(" ", namelist);
++ list_display(NULL, " ", namelist);
+ printf("\n");
+- *response = noyes(_n(
++ *response = noyes(NULL, _n(
+ "Do you want to skip the above package for this upgrade?",
+ "Do you want to skip the above packages for this upgrade?",
+ count));
+@@ -320,7 +320,7 @@ void cb_question(alpm_question_t event,
+ alpm_list_t *providers = (alpm_list_t *)data1;
+ size_t count = alpm_list_count(providers);
+ char *depstring = alpm_dep_compute_string((alpm_depend_t *)data2);
+- printf(_(":: There are %zd providers available for %s:\n"), count,
++ color_printf(COLOR_DOUBLECOLON, _(":: There are %zd providers available for %s:\n"), count,
+ depstring);
+ free(depstring);
+ select_display(providers);
+@@ -329,7 +329,7 @@ void cb_question(alpm_question_t event,
+ break;
+ case ALPM_QUESTION_LOCAL_NEWER:
+ if(!config->op_s_downloadonly) {
+- *response = yesno(_(":: %s-%s: local version is newer. Upgrade anyway?"),
++ *response = yesno(COLOR_DOUBLECOLON, _(":: %s-%s: local version is newer. Upgrade anyway?"),
+ alpm_pkg_get_name(data1),
+ alpm_pkg_get_version(data1));
+ } else {
+@@ -337,7 +337,7 @@ void cb_question(alpm_question_t event,
+ }
+ break;
+ case ALPM_QUESTION_CORRUPTED_PKG:
+- *response = yesno(_(":: File %s is corrupted (%s).\n"
++ *response = yesno(COLOR_DOUBLECOLON, _(":: File %s is corrupted (%s).\n"
+ "Do you want to delete it?"),
+ (char *)data1,
+ alpm_strerror(*(enum _alpm_errno_t *)data2));
+@@ -347,7 +347,7 @@ void cb_question(alpm_question_t event,
+ alpm_pgpkey_t *key = data1;
+ char created[12];
+ strftime(created, 12, "%Y-%m-%d", localtime(&(key->created)));
+- *response = yesno(_(":: Import PGP key %s, \"%s\", created %s?"),
++ *response = yesno(COLOR_DOUBLECOLON, _(":: Import PGP key %s, \"%s\", created %s?"),
+ key->fingerprint, key->uid, created);
+ }
+ break;
+@@ -481,8 +481,9 @@ void cb_progress(alpm_progress_t event,
+
+ }
+
+- printf("(%*ld/%*ld) %ls%-*s", digits, (unsigned long)current,
+- digits, (unsigned long)howmany, wcstr, padwid, "");
++ color_printf(COLOR_BLUE_ALL, "(%*ld/%*ld)", digits, (unsigned long)current,
++ digits, (unsigned long)howmany);
++ printf(" %ls%-*s", wcstr, padwid, "");
+
+ free(wcstr);
+
+diff -up -Npaur a/src/pacman/package.c b/src/pacman/package.c
+--- a/src/pacman/package.c 2012-02-03 01:18:52.000000000 +0200
++++ b/src/pacman/package.c 2012-07-20 21:48:20.266827634 +0300
+@@ -41,7 +41,7 @@
+ * @param deps a list with items of type alpm_depend_t
+ * @return a string list, must be freed
+ */
+-static void deplist_display(const char *title,
++static void deplist_display(const colordata_t *colors_title, const char *title,
+ alpm_list_t *deps)
+ {
+ alpm_list_t *i, *text = NULL;
+@@ -49,7 +49,7 @@ static void deplist_display(const char *
+ alpm_depend_t *dep = alpm_list_getdata(i);
+ text = alpm_list_add(text, alpm_dep_compute_string(dep));
+ }
+- list_display(title, text);
++ list_display(colors_title, title, text);
+ FREELIST(text);
+ }
+
+@@ -102,65 +102,65 @@ void dump_pkg_full(alpm_pkg_t *pkg, int
+
+ /* actual output */
+ if(from == PKG_FROM_SYNCDB) {
+- string_display(_("Repository :"),
+- alpm_db_get_name(alpm_pkg_get_db(pkg)));
++ color_string_display(COLOR_WHITE_ALL, _("Repository :"),
++ COLOR_MAGENTA_ALL, alpm_db_get_name(alpm_pkg_get_db(pkg)));
+ }
+- string_display(_("Name :"), alpm_pkg_get_name(pkg));
+- string_display(_("Version :"), alpm_pkg_get_version(pkg));
+- string_display(_("URL :"), alpm_pkg_get_url(pkg));
+- list_display(_("Licenses :"), alpm_pkg_get_licenses(pkg));
+- list_display(_("Groups :"), alpm_pkg_get_groups(pkg));
+- deplist_display(_("Provides :"), alpm_pkg_get_provides(pkg));
+- deplist_display(_("Depends On :"), alpm_pkg_get_depends(pkg));
+- list_display_linebreak(_("Optional Deps :"), alpm_pkg_get_optdepends(pkg));
++ color_string_display(COLOR_WHITE_ALL, _("Name :"), COLOR_WHITE_ALL, alpm_pkg_get_name(pkg));
++ color_string_display(COLOR_WHITE_ALL, _("Version :"), COLOR_GREEN_ALL, alpm_pkg_get_version(pkg));
++ color_string_display(COLOR_WHITE_ALL, _("URL :"), COLOR_CYAN_ALL, alpm_pkg_get_url(pkg));
++ list_display(COLOR_WHITE_ALL, _("Licenses :"), alpm_pkg_get_licenses(pkg));
++ list_display(COLOR_WHITE_ALL, _("Groups :"), alpm_pkg_get_groups(pkg));
++ deplist_display(COLOR_WHITE_ALL, _("Provides :"), alpm_pkg_get_provides(pkg));
++ deplist_display(COLOR_WHITE_ALL, _("Depends On :"), alpm_pkg_get_depends(pkg));
++ list_display_linebreak(COLOR_WHITE_ALL, _("Optional Deps :"), alpm_pkg_get_optdepends(pkg));
+ if(extra || from == PKG_FROM_LOCALDB) {
+- list_display(_("Required By :"), requiredby);
++ list_display(COLOR_WHITE_ALL, _("Required By :"), requiredby);
+ }
+- deplist_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg));
+- deplist_display(_("Replaces :"), alpm_pkg_get_replaces(pkg));
++ deplist_display(COLOR_WHITE_ALL, _("Conflicts With :"), alpm_pkg_get_conflicts(pkg));
++ deplist_display(COLOR_WHITE_ALL, _("Replaces :"), alpm_pkg_get_replaces(pkg));
+
+ size = humanize_size(alpm_pkg_get_size(pkg), 'K', 2, &label);
+ if(from == PKG_FROM_SYNCDB) {
+- printf(_("Download Size : %6.2f %s\n"), size, label);
++ color_printf(COLOR_WHITE_COLON, _("Download Size : %6.2f %s\n"), size, label);
+ } else if(from == PKG_FROM_FILE) {
+- printf(_("Compressed Size: %6.2f %s\n"), size, label);
++ color_printf(COLOR_WHITE_COLON, _("Compressed Size: %6.2f %s\n"), size, label);
+ }
+
+ size = humanize_size(alpm_pkg_get_isize(pkg), 'K', 2, &label);
+- printf(_("Installed Size : %6.2f %s\n"), size, label);
++ color_printf(COLOR_WHITE_COLON, _("Installed Size : %6.2f %s\n"), size, label);
+
+- string_display(_("Packager :"), alpm_pkg_get_packager(pkg));
+- string_display(_("Architecture :"), alpm_pkg_get_arch(pkg));
+- string_display(_("Build Date :"), bdatestr);
++ string_display(COLOR_WHITE_ALL, _("Packager :"), alpm_pkg_get_packager(pkg));
++ string_display(COLOR_WHITE_ALL, _("Architecture :"), alpm_pkg_get_arch(pkg));
++ string_display(COLOR_WHITE_ALL, _("Build Date :"), bdatestr);
+ if(from == PKG_FROM_LOCALDB) {
+- string_display(_("Install Date :"), idatestr);
+- string_display(_("Install Reason :"), reason);
++ string_display(COLOR_WHITE_ALL, _("Install Date :"), idatestr);
++ string_display(COLOR_WHITE_ALL, _("Install Reason :"), reason);
+ }
+ if(from == PKG_FROM_FILE || from == PKG_FROM_LOCALDB) {
+- string_display(_("Install Script :"),
++ string_display(COLOR_WHITE_ALL, _("Install Script :"),
+ alpm_pkg_has_scriptlet(pkg) ? _("Yes") : _("No"));
+ }
+
+ if(from == PKG_FROM_SYNCDB) {
+- string_display(_("MD5 Sum :"), alpm_pkg_get_md5sum(pkg));
+- string_display(_("SHA256 Sum :"), alpm_pkg_get_sha256sum(pkg));
+- string_display(_("Signatures :"),
++ string_display(COLOR_WHITE_ALL, _("MD5 Sum :"), alpm_pkg_get_md5sum(pkg));
++ string_display(COLOR_WHITE_ALL, _("SHA256 Sum :"), alpm_pkg_get_sha256sum(pkg));
++ string_display(COLOR_WHITE_ALL, _("Signatures :"),
+ alpm_pkg_get_base64_sig(pkg) ? _("Yes") : _("None"));
+ }
+ if(from == PKG_FROM_FILE) {
+ alpm_siglist_t siglist;
+ int err = alpm_pkg_check_pgp_signature(pkg, &siglist);
+ if(err && alpm_errno(config->handle) == ALPM_ERR_SIG_MISSING) {
+- string_display(_("Signatures :"), _("None"));
++ string_display(COLOR_WHITE_ALL, _("Signatures :"), _("None"));
+ } else if(err) {
+- string_display(_("Signatures :"),
++ string_display(COLOR_WHITE_ALL, _("Signatures :"),
+ alpm_strerror(alpm_errno(config->handle)));
+ } else {
+ signature_display(_("Signatures :"), &siglist);
+ }
+ alpm_siglist_cleanup(&siglist);
+ }
+- string_display(_("Description :"), alpm_pkg_get_desc(pkg));
++ string_display(COLOR_WHITE_ALL, _("Description :"), alpm_pkg_get_desc(pkg));
+
+ /* Print additional package info if info flag passed more than once */
+ if(from == PKG_FROM_LOCALDB && extra) {
+@@ -219,7 +219,7 @@ void dump_pkg_backups(alpm_pkg_t *pkg)
+ {
+ alpm_list_t *i;
+ const char *root = alpm_option_get_root(config->handle);
+- printf(_("Backup Files:\n"));
++ color_printf(COLOR_WHITE_ALL, _("Backup Files:\n"));
+ if(alpm_pkg_get_backup(pkg)) {
+ /* package has backup files, so print them */
+ for(i = alpm_pkg_get_backup(pkg); i; i = alpm_list_next(i)) {
+@@ -252,7 +252,8 @@ void dump_pkg_files(alpm_pkg_t *pkg, int
+ for(i = 0; i < pkgfiles->count; i++) {
+ const alpm_file_t *file = pkgfiles->files + i;
+ if(!quiet) {
+- printf("%s %s%s\n", pkgname, root, file->name);
++ color_printf(COLOR_WHITE_ALL, "%s", pkgname);
++ printf(" %s%s\n", root, file->name);
+ } else {
+ printf("%s%s\n", root, file->name);
+ }
+diff -up -Npaur a/src/pacman/pacman.c b/src/pacman/pacman.c
+--- a/src/pacman/pacman.c 2012-02-15 23:57:20.000000000 +0200
++++ b/src/pacman/pacman.c 2012-07-20 21:48:20.266827634 +0300
+@@ -219,11 +219,23 @@ static void usage(int op, const char * c
+ */
+ static void version(void)
+ {
++ color_printf(COLOR_YELLOW_ALL, " .--. ");
++ printf(" ");
++ color_printf(COLOR_RED_ALL, " .---. ");
++ printf(" Pacman-color v%s - libalpm v%s\n", PACKAGE_VERSION, alpm_version());
++ color_printf(COLOR_YELLOW_ALL, "/ _.-'");
++ color_printf(COLOR_WHITE_ALL, " .-. .-");
++ color_printf(COLOR_RED_ALL, "|O O |");
++ printf(" Copyright (C) 2006-2012 Pacman Development Team\n");
++ color_printf(COLOR_YELLOW_ALL, "\\ '-.");
++ color_printf(COLOR_WHITE_ALL, " '-' '-");
++ color_printf(COLOR_RED_ALL, "|~~~ |");
++ printf(" Copyright (C) 2002-2006 Judd Vinet\n");
++ color_printf(COLOR_YELLOW_ALL, " '--' ");
++ printf(" ");
++ color_printf(COLOR_RED_ALL, "|.-.-.|");
++ printf(" Colored by vogo <vogo(at)seznam(dot)cz>\n");
+ printf("\n");
+- printf(" .--. Pacman v%s - libalpm v%s\n", PACKAGE_VERSION, alpm_version());
+- printf("/ _.-' .-. .-. .-. Copyright (C) 2006-2012 Pacman Development Team\n");
+- printf("\\ '-. '-' '-' '-' Copyright (C) 2002-2006 Judd Vinet\n");
+- printf(" '--'\n");
+ printf(_(" This program may be freely redistributed under\n"
+ " the terms of the GNU General Public License.\n"));
+ printf("\n");
+@@ -795,6 +807,7 @@ int main(int argc, char *argv[])
+
+ /* init config data */
+ config = config_new();
++ parsecolorconfig();
+
+ /* disable progressbar if the output is redirected */
+ if(!isatty(fileno(stdout))) {
+@@ -896,18 +909,18 @@ int main(int argc, char *argv[])
+
+ if(config->verbose > 0) {
+ alpm_list_t *i;
+- printf("Root : %s\n", alpm_option_get_root(config->handle));
+- printf("Conf File : %s\n", config->configfile);
+- printf("DB Path : %s\n", alpm_option_get_dbpath(config->handle));
+- printf("Cache Dirs: ");
++ string_display(COLOR_WHITE_ALL, "Root :", alpm_option_get_root(config->handle));
++ string_display(COLOR_WHITE_ALL, "Conf File :", config->configfile);
++ string_display(COLOR_WHITE_ALL, "DB Path :", alpm_option_get_dbpath(config->handle));
++ color_printf(COLOR_WHITE_ALL, "Cache Dirs: ");
+ for(i = alpm_option_get_cachedirs(config->handle); i; i = alpm_list_next(i)) {
+ printf("%s ", (char *)alpm_list_getdata(i));
+ }
+ printf("\n");
+- printf("Lock File : %s\n", alpm_option_get_lockfile(config->handle));
+- printf("Log File : %s\n", alpm_option_get_logfile(config->handle));
+- printf("GPG Dir : %s\n", alpm_option_get_gpgdir(config->handle));
+- list_display("Targets :", pm_targets);
++ string_display(COLOR_WHITE_ALL, "Lock File :", alpm_option_get_lockfile(config->handle));
++ string_display(COLOR_WHITE_ALL, "Log File :", alpm_option_get_logfile(config->handle));
++ string_display(COLOR_WHITE_ALL, "GPG Dir :", alpm_option_get_gpgdir(config->handle));
++ list_display(COLOR_WHITE_ALL, "Targets :", pm_targets);
+ }
+
+ /* Log command line */
+diff -up -Npaur a/src/pacman/query.c b/src/pacman/query.c
+--- a/src/pacman/query.c 2011-12-23 22:36:36.000000000 +0200
++++ b/src/pacman/query.c 2012-07-20 21:48:20.268827634 +0300
+@@ -266,7 +266,9 @@ static int query_search(alpm_list_t *tar
+ alpm_pkg_t *pkg = alpm_list_getdata(i);
+
+ if(!config->quiet) {
+- printf("local/%s %s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
++ color_printf(COLOR_MAGENTA_ALL, "local/");
++ color_printf(COLOR_WHITE_ALL, "%s ", alpm_pkg_get_name(pkg));
++ color_printf(COLOR_GREEN_ALL, "%s", alpm_pkg_get_version(pkg));
+ } else {
+ printf("%s", alpm_pkg_get_name(pkg));
+ }
+@@ -275,16 +277,11 @@ static int query_search(alpm_list_t *tar
+ if(!config->quiet) {
+ if((grp = alpm_pkg_get_groups(pkg)) != NULL) {
+ alpm_list_t *k;
+- printf(" (");
++ color_printf(COLOR_BLUE_ALL, " (");
+ for(k = grp; k; k = alpm_list_next(k)) {
+ const char *group = alpm_list_getdata(k);
+- printf("%s", group);
+- if(alpm_list_next(k)) {
+- /* only print a spacer if there are more groups */
+- printf(" ");
+- }
++ color_printf(COLOR_BLUE_ALL, "%s%s", group, (alpm_list_next(k) ? " " : ")"));
+ }
+- printf(")");
+ }
+
+ /* we need a newline and initial indent first */
+@@ -315,7 +312,8 @@ static int query_group(alpm_list_t *targ
+
+ for(p = grp->packages; p; p = alpm_list_next(p)) {
+ alpm_pkg_t *pkg = alpm_list_getdata(p);
+- printf("%s %s\n", grp->name, alpm_pkg_get_name(pkg));
++ color_printf(COLOR_BLUE_ALL, "%s ", grp->name);
++ color_printf(COLOR_WHITE_ALL, "%s\n", alpm_pkg_get_name(pkg));
+ }
+ }
+ } else {
+@@ -327,8 +325,8 @@ static int query_group(alpm_list_t *targ
+ const alpm_list_t *p;
+ for(p = grp->packages; p; p = alpm_list_next(p)) {
+ if(!config->quiet) {
+- printf("%s %s\n", grpname,
+- alpm_pkg_get_name(alpm_list_getdata(p)));
++ color_printf(COLOR_BLUE_ALL, "%s ", grpname);
++ color_printf(COLOR_WHITE_ALL, "%s\n", alpm_pkg_get_name(alpm_list_getdata(p)));
+ } else {
+ printf("%s\n", alpm_pkg_get_name(alpm_list_getdata(p)));
+ }
+@@ -478,7 +476,8 @@ static int display(alpm_pkg_t *pkg)
+ if(!config->op_q_info && !config->op_q_list
+ && !config->op_q_changelog && !config->op_q_check) {
+ if(!config->quiet) {
+- printf("%s %s\n", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
++ color_printf(COLOR_WHITE_ALL, "%s ", alpm_pkg_get_name(pkg));
++ color_printf(COLOR_GREEN_ALL, "%s\n", alpm_pkg_get_version(pkg));
+ } else {
+ printf("%s\n", alpm_pkg_get_name(pkg));
+ }
+diff -up -Npaur a/src/pacman/remove.c b/src/pacman/remove.c
+--- a/src/pacman/remove.c 2012-02-06 13:36:22.000000000 +0200
++++ b/src/pacman/remove.c 2012-07-20 21:48:20.268827634 +0300
+@@ -111,14 +111,14 @@ int pacman_remove(alpm_list_t *targets)
+ case ALPM_ERR_PKG_INVALID_ARCH:
+ for(i = data; i; i = alpm_list_next(i)) {
+ char *pkg = alpm_list_getdata(i);
+- printf(_(":: package %s does not have a valid architecture\n"), pkg);
++ color_printf(COLOR_DOUBLECOLON, _(":: package %s does not have a valid architecture\n"), pkg);
+ }
+ break;
+ case ALPM_ERR_UNSATISFIED_DEPS:
+ for(i = data; i; i = alpm_list_next(i)) {
+ alpm_depmissing_t *miss = alpm_list_getdata(i);
+ char *depstring = alpm_dep_compute_string(miss->depend);
+- printf(_(":: %s: requires %s\n"), miss->target, depstring);
++ color_printf(COLOR_DOUBLECOLON, _(":: %s: requires %s\n"), miss->target, depstring);
+ free(depstring);
+ }
+ break;
+@@ -140,7 +140,7 @@ int pacman_remove(alpm_list_t *targets)
+ holdpkg = 1;
+ }
+ }
+- if(holdpkg && (noyes(_("HoldPkg was found in target list. Do you want to continue?")) == 0)) {
++ if(holdpkg && (noyes(NULL, _("HoldPkg was found in target list. Do you want to continue?")) == 0)) {
+ retval = 1;
+ goto cleanup;
+ }
+@@ -160,7 +160,7 @@ int pacman_remove(alpm_list_t *targets)
+ /* print targets and ask user confirmation */
+ display_targets();
+ printf("\n");
+- if(yesno(_("Do you want to remove these packages?")) == 0) {
++ if(yesno(NULL, _("Do you want to remove these packages?")) == 0) {
+ retval = 1;
+ goto cleanup;
+ }
+diff -up -Npaur a/src/pacman/sync.c b/src/pacman/sync.c
+--- a/src/pacman/sync.c 2012-03-13 15:24:11.000000000 +0200
++++ b/src/pacman/sync.c 2012-07-20 21:48:20.269827634 +0300
+@@ -146,8 +146,8 @@ static int sync_cleandb_all(void)
+ int ret = 0;
+
+ dbpath = alpm_option_get_dbpath(config->handle);
+- printf(_("Database directory: %s\n"), dbpath);
+- if(!yesno(_("Do you want to remove unused repositories?"))) {
++ color_printf(COLOR_WHITE_COLON, _("Database directory: %s\n"), dbpath);
++ if(!yesno(NULL, _("Do you want to remove unused repositories?"))) {
+ return 0;
+ }
+ printf(_("removing unused sync repositories...\n"));
+@@ -175,7 +175,7 @@ static int sync_cleancache(int level)
+ int ret = 0;
+
+ for(i = cachedirs; i; i = alpm_list_next(i)) {
+- printf(_("Cache directory: %s\n"), (char *)alpm_list_getdata(i));
++ color_printf(COLOR_WHITE_COLON, _("Cache directory: %s\n"), (char *)alpm_list_getdata(i));
+ }
+
+ if(!config->cleanmethod) {
+@@ -184,19 +184,19 @@ static int sync_cleancache(int level)
+ }
+
+ if(level == 1) {
+- printf(_("Packages to keep:\n"));
++ color_printf(COLOR_WHITE_COLON, _("Packages to keep:\n"));
+ if(config->cleanmethod & PM_CLEAN_KEEPINST) {
+ printf(_(" All locally installed packages\n"));
+ }
+ if(config->cleanmethod & PM_CLEAN_KEEPCUR) {
+ printf(_(" All current sync database packages\n"));
+ }
+- if(!yesno(_("Do you want to remove all other packages from cache?"))) {
++ if(!yesno(NULL, _("Do you want to remove all other packages from cache?"))) {
+ return 0;
+ }
+ printf(_("removing old packages from cache...\n"));
+ } else {
+- if(!noyes(_("Do you want to remove ALL files from cache?"))) {
++ if(!noyes(NULL, _("Do you want to remove ALL files from cache?"))) {
+ return 0;
+ }
+ printf(_("removing all files from cache...\n"));
+@@ -345,9 +345,9 @@ static void print_installed(alpm_db_t *d
+ if(lpkg) {
+ const char *lpkgver = alpm_pkg_get_version(lpkg);
+ if(strcmp(lpkgver,pkgver) == 0) {
+- printf(" [%s]", _("installed"));
++ color_printf(COLOR_CYAN_ALL, " [%s]", _("installed"));
+ } else {
+- printf(" [%s: %s]", _("installed"), lpkgver);
++ color_printf(COLOR_CYAN_ALL, " [%s: %s]", _("installed"), lpkgver);
+ }
+ }
+ }
+@@ -380,8 +380,9 @@ static int sync_search(alpm_list_t *sync
+ alpm_pkg_t *pkg = alpm_list_getdata(j);
+
+ if(!config->quiet) {
+- printf("%s/%s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg),
+- alpm_pkg_get_version(pkg));
++ color_printf(COLOR_MAGENTA_ALL, "%s/", alpm_db_get_name(db));
++ color_printf(COLOR_WHITE_ALL, "%s ", alpm_pkg_get_name(pkg));
++ color_printf(COLOR_GREEN_ALL, "%s", alpm_pkg_get_version(pkg));
+ } else {
+ printf("%s", alpm_pkg_get_name(pkg));
+ }
+@@ -389,16 +390,11 @@ static int sync_search(alpm_list_t *sync
+ if(!config->quiet) {
+ if((grp = alpm_pkg_get_groups(pkg)) != NULL) {
+ alpm_list_t *k;
+- printf(" (");
++ color_printf(COLOR_BLUE_ALL, " (");
+ for(k = grp; k; k = alpm_list_next(k)) {
+ const char *group = alpm_list_getdata(k);
+- printf("%s", group);
+- if(alpm_list_next(k)) {
+- /* only print a spacer if there are more groups */
+- printf(" ");
+- }
++ color_printf(COLOR_BLUE_ALL, "%s%s", group, (alpm_list_next(k) ? " " : ")"));
+ }
+- printf(")");
+ }
+
+ print_installed(db_local, pkg);
+@@ -433,8 +429,8 @@ static int sync_group(int level, alpm_li
+ /* get names of packages in group */
+ for(k = grp->packages; k; k = alpm_list_next(k)) {
+ if(!config->quiet) {
+- printf("%s %s\n", grpname,
+- alpm_pkg_get_name(alpm_list_getdata(k)));
++ color_printf(COLOR_BLUE_ALL, "%s ", grpname);
++ color_printf(COLOR_WHITE_ALL, "%s\n", alpm_pkg_get_name(alpm_list_getdata(k)));
+ } else {
+ printf("%s\n", alpm_pkg_get_name(alpm_list_getdata(k)));
+ }
+@@ -451,8 +447,8 @@ static int sync_group(int level, alpm_li
+
+ if(level > 1) {
+ for(k = grp->packages; k; k = alpm_list_next(k)) {
+- printf("%s %s\n", grp->name,
+- alpm_pkg_get_name(alpm_list_getdata(k)));
++ color_printf(COLOR_BLUE_ALL, "%s ", grp->name);
++ color_printf(COLOR_WHITE_ALL, "%s\n", alpm_pkg_get_name(alpm_list_getdata(k)));
+ }
+ } else {
+ /* print grp names only, no package names */
+@@ -570,8 +566,9 @@ static int sync_list(alpm_list_t *syncs,
+ alpm_pkg_t *pkg = alpm_list_getdata(j);
+
+ if(!config->quiet) {
+- printf("%s %s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg),
+- alpm_pkg_get_version(pkg));
++ color_printf(COLOR_MAGENTA_ALL, "%s ", alpm_db_get_name(db));
++ color_printf(COLOR_WHITE_ALL, "%s ", alpm_pkg_get_name(pkg));
++ color_printf(COLOR_GREEN_ALL, "%s", alpm_pkg_get_version(pkg));
+ print_installed(db_local, pkg);
+ printf("\n");
+ } else {
+@@ -654,7 +651,7 @@ static int process_group(alpm_list_t *db
+
+
+ if(config->print == 0) {
+- printf(_(":: There are %d members in group %s:\n"), count,
++ color_printf(COLOR_DOUBLECOLON, _(":: There are %d members in group %s:\n"), count,
+ group);
+ select_display(pkgs);
+ char *array = malloc(count);
+@@ -771,7 +768,7 @@ static int sync_trans(alpm_list_t *targe
+ }
+
+ if(config->op_s_upgrade) {
+- printf(_(":: Starting full system upgrade...\n"));
++ color_printf(COLOR_DOUBLECOLON, _(":: Starting full system upgrade...\n"));
+ alpm_logaction(config->handle, "starting full system upgrade\n");
+ if(alpm_sync_sysupgrade(config->handle, config->op_s_upgrade >= 2) == -1) {
+ pm_printf(ALPM_LOG_ERROR, "%s\n", alpm_strerror(alpm_errno(config->handle)));
+@@ -797,14 +794,14 @@ int sync_prepare_execute(void)
+ case ALPM_ERR_PKG_INVALID_ARCH:
+ for(i = data; i; i = alpm_list_next(i)) {
+ char *pkg = alpm_list_getdata(i);
+- printf(_(":: package %s does not have a valid architecture\n"), pkg);
++ color_printf(COLOR_DOUBLECOLON, _(":: package %s does not have a valid architecture\n"), pkg);
+ }
+ break;
+ case ALPM_ERR_UNSATISFIED_DEPS:
+ for(i = data; i; i = alpm_list_next(i)) {
+ alpm_depmissing_t *miss = alpm_list_getdata(i);
+ char *depstring = alpm_dep_compute_string(miss->depend);
+- printf(_(":: %s: requires %s\n"), miss->target, depstring);
++ color_printf(COLOR_DOUBLECOLON, _(":: %s: requires %s\n"), miss->target, depstring);
+ free(depstring);
+ }
+ break;
+@@ -813,11 +810,11 @@ int sync_prepare_execute(void)
+ alpm_conflict_t *conflict = alpm_list_getdata(i);
+ /* only print reason if it contains new information */
+ if(conflict->reason->mod == ALPM_DEP_MOD_ANY) {
+- printf(_(":: %s and %s are in conflict\n"),
++ color_printf(COLOR_DOUBLECOLON, _(":: %s and %s are in conflict\n"),
+ conflict->package1, conflict->package2);
+ } else {
+ char *reason = alpm_dep_compute_string(conflict->reason);
+- printf(_(":: %s and %s are in conflict (%s)\n"),
++ color_printf(COLOR_DOUBLECOLON, _(":: %s and %s are in conflict (%s)\n"),
+ conflict->package1, conflict->package2, reason);
+ free(reason);
+ }
+@@ -850,9 +847,9 @@ int sync_prepare_execute(void)
+
+ int confirm;
+ if(config->op_s_downloadonly) {
+- confirm = yesno(_("Proceed with download?"));
++ confirm = yesno(NULL, _("Proceed with download?"));
+ } else {
+- confirm = yesno(_("Proceed with installation?"));
++ confirm = yesno(NULL, _("Proceed with installation?"));
+ }
+ if(!confirm) {
+ goto cleanup;
+@@ -872,7 +869,7 @@ int sync_prepare_execute(void)
+ conflict->file, conflict->target, conflict->ctarget);
+ break;
+ case ALPM_FILECONFLICT_FILESYSTEM:
+- printf(_("%s: %s exists in filesystem\n"),
++ color_printf(COLOR_WHITE_COLON, _("%s: %s exists in filesystem\n"),
+ conflict->target, conflict->file);
+ break;
+ }
+@@ -891,7 +888,7 @@ int sync_prepare_execute(void)
+ break;
+ }
+ /* TODO: stderr? */
+- printf(_("Errors occurred, no packages were upgraded.\n"));
++ color_printf(COLOR_RED_ALL, _("Errors occurred, no packages were upgraded.\n"));
+ retval = 1;
+ goto cleanup;
+ }
+@@ -939,7 +936,7 @@ int pacman_sync(alpm_list_t *targets)
+
+ if(config->op_s_sync) {
+ /* grab a fresh package list */
+- printf(_(":: Synchronizing package databases...\n"));
++ color_printf(COLOR_DOUBLECOLON, _(":: Synchronizing package databases...\n"));
+ alpm_logaction(config->handle, "synchronizing package lists\n");
+ if(!sync_synctree(config->op_s_sync, sync_dbs)) {
+ return 1;
+@@ -992,9 +989,9 @@ int pacman_sync(alpm_list_t *targets)
+ alpm_list_t *tmp = NULL;
+ if(config->op_s_upgrade || (tmp = alpm_list_diff(targets, packages, (alpm_list_fn_cmp)strcmp))) {
+ alpm_list_free(tmp);
+- printf(_(":: The following packages should be upgraded first :\n"));
+- list_display(" ", packages);
+- if(yesno(_(":: Do you want to cancel the current operation\n"
++ color_printf(COLOR_DOUBLECOLON, _(":: The following packages should be upgraded first :\n"));
++ list_display(NULL, " ", packages);
++ if(yesno(COLOR_DOUBLECOLON2, _(":: Do you want to cancel the current operation\n"
+ ":: and upgrade these packages now?"))) {
+ FREELIST(targs);
+ targs = packages;
+diff -up -Npaur a/src/pacman/util.c b/src/pacman/util.c
+--- a/src/pacman/util.c 2012-02-20 07:18:31.000000000 +0200
++++ b/src/pacman/util.c 2012-07-20 21:48:20.270827634 +0300
+@@ -48,6 +48,20 @@
+ #include "conf.h"
+ #include "callback.h"
+
++#define COLOR_LEN 8
++
++typedef struct __colortab_t {
++ char red[COLOR_LEN + 1];
++ char green[COLOR_LEN + 1];
++ char yellow[COLOR_LEN + 1];
++ char blue[COLOR_LEN + 1];
++ char magenta[COLOR_LEN + 1];
++ char cyan[COLOR_LEN + 1];
++ char white[COLOR_LEN + 1];
++ char none[COLOR_LEN + 1];
++} colortab_t;
++
++static colortab_t colortab;
+
+ int trans_init(alpm_transflag_t flags, int check_valid)
+ {
+@@ -463,10 +477,10 @@ static size_t string_length(const char *
+ return len;
+ }
+
+-void string_display(const char *title, const char *string)
++void string_display(const colordata_t *colors_title, const char *title, const char *string)
+ {
+ if(title) {
+- printf("%s ", title);
++ color_printf(colors_title, "%s ", title);
+ }
+ if(string == NULL || string[0] == '\0') {
+ printf(_("None"));
+@@ -599,14 +613,14 @@ int table_display(const char *title, con
+ return 0;
+ }
+
+-void list_display(const char *title, const alpm_list_t *list)
++void list_display(const colordata_t *colors_title, const char *title, const alpm_list_t *list)
+ {
+ const alpm_list_t *i;
+ size_t len = 0;
+
+ if(title) {
+ len = string_length(title) + 1;
+- printf("%s ", title);
++ color_printf(colors_title, "%s ", title);
+ }
+
+ if(!list) {
+@@ -640,13 +654,13 @@ void list_display(const char *title, con
+ }
+ }
+
+-void list_display_linebreak(const char *title, const alpm_list_t *list)
++void list_display_linebreak(const colordata_t *colors_title, const char *title, const alpm_list_t *list)
+ {
+ size_t len = 0;
+
+ if(title) {
+ len = string_length(title) + 1;
+- printf("%s ", title);
++ color_printf(colors_title, "%s ", title);
+ }
+
+ if(!list) {
+@@ -867,11 +881,11 @@ static void _display_targets(alpm_list_t
+ alpm_list_t *header = create_verbose_header(show_dl_size);
+ if(table_display(str, header, rows) != 0) {
+ /* fallback to list display if table wouldn't fit */
+- list_display(str, names);
++ list_display(COLOR_YELLOW_ALL, str, names);
+ }
+ alpm_list_free(header);
+ } else {
+- list_display(str, names);
++ list_display(COLOR_YELLOW_ALL, str, names);
+ }
+ printf("\n");
+
+@@ -886,21 +900,21 @@ static void _display_targets(alpm_list_t
+
+ if(dlsize > 0 || config->op_s_downloadonly) {
+ size = humanize_size(dlsize, 'M', 2, &label);
+- printf(_("Total Download Size: %.2f %s\n"), size, label);
++ color_printf(COLOR_WHITE_COLON, _("Total Download Size: %.2f %s\n"), size, label);
+ }
+ if(!config->op_s_downloadonly) {
+ if(isize > 0) {
+ size = humanize_size(isize, 'M', 2, &label);
+- printf(_("Total Installed Size: %.2f %s\n"), size, label);
++ color_printf(COLOR_WHITE_COLON, _("Total Installed Size: %.2f %s\n"), size, label);
+ }
+ if(rsize > 0 && isize == 0) {
+ size = humanize_size(rsize, 'M', 2, &label);
+- printf(_("Total Removed Size: %.2f %s\n"), size, label);
++ color_printf(COLOR_WHITE_COLON, _("Total Removed Size: %.2f %s\n"), size, label);
+ }
+ /* only show this net value if different from raw installed size */
+ if(isize > 0 && rsize > 0) {
+ size = humanize_size(isize - rsize, 'M', 2, &label);
+- printf(_("Net Upgrade Size: %.2f %s\n"), size, label);
++ color_printf(COLOR_WHITE_COLON, _("Net Upgrade Size: %.2f %s\n"), size, label);
+ }
+ }
+ }
+@@ -1115,7 +1129,7 @@ void display_new_optdepends(alpm_pkg_t *
+ alpm_list_t *optdeps = alpm_list_diff(new,old,str_cmp);
+ if(optdeps) {
+ printf(_("New optional dependencies for %s\n"), alpm_pkg_get_name(newpkg));
+- list_display_linebreak(" ", optdeps);
++ list_display_linebreak(NULL, " ", optdeps);
+ }
+ alpm_list_free(optdeps);
+ }
+@@ -1125,7 +1139,7 @@ void display_optdepends(alpm_pkg_t *pkg)
+ alpm_list_t *optdeps = alpm_pkg_get_optdepends(pkg);
+ if(optdeps) {
+ printf(_("Optional dependencies for %s\n"), alpm_pkg_get_name(pkg));
+- list_display_linebreak(" ", optdeps);
++ list_display_linebreak(NULL, " ", optdeps);
+ }
+ }
+
+@@ -1133,9 +1147,9 @@ static void display_repo_list(const char
+ {
+ const char *prefix= " ";
+
+- printf(":: ");
+- printf(_("Repository %s\n"), dbname);
+- list_display(prefix, list);
++ color_printf(COLOR_BLUE_ALL, ":: ");
++ color_printf(COLOR_WHITE_ALL, _("Repository %s\n"), dbname);
++ list_display(NULL, prefix, list);
+ }
+
+ void select_display(const alpm_list_t *pkglist)
+@@ -1354,7 +1368,7 @@ int select_question(int count)
+
+
+ /* presents a prompt and gets a Y/N answer */
+-static int question(short preset, char *fmt, va_list args)
++static int question(const colordata_t *colors, short preset, char *fmt, va_list args)
+ {
+ char response[32];
+ FILE *stream;
+@@ -1370,7 +1384,7 @@ static int question(short preset, char *
+ fflush(stdout);
+ fflush(stderr);
+
+- vfprintf(stream, fmt, args);
++ color_vfprintf(stream, colors, fmt, args);
+
+ if(preset) {
+ fprintf(stream, " %s ", _("[Y/n]"));
+@@ -1407,25 +1421,25 @@ static int question(short preset, char *
+ return 0;
+ }
+
+-int yesno(char *fmt, ...)
++int yesno(const colordata_t *colors, char *fmt, ...)
+ {
+ int ret;
+ va_list args;
+
+ va_start(args, fmt);
+- ret = question(1, fmt, args);
++ ret = question(colors, 1, fmt, args);
+ va_end(args);
+
+ return ret;
+ }
+
+-int noyes(char *fmt, ...)
++int noyes(const colordata_t *colors, char *fmt, ...)
+ {
+ int ret;
+ va_list args;
+
+ va_start(args, fmt);
+- ret = question(0, fmt, args);
++ ret = question(colors, 0, fmt, args);
+ va_end(args);
+
+ return ret;
+@@ -1474,22 +1488,42 @@ int pm_vasprintf(char **string, alpm_log
+ ret = vasprintf(&msg, format, args);
+
+ /* print a prefix to the message */
+- switch(level) {
+- case ALPM_LOG_ERROR:
+- pm_asprintf(string, _("error: %s"), msg);
+- break;
+- case ALPM_LOG_WARNING:
+- pm_asprintf(string, _("warning: %s"), msg);
+- break;
+- case ALPM_LOG_DEBUG:
+- pm_asprintf(string, "debug: %s", msg);
+- break;
+- case ALPM_LOG_FUNCTION:
+- pm_asprintf(string, "function: %s", msg);
+- break;
+- default:
+- pm_asprintf(string, "%s", msg);
+- break;
++ if(isatty(fileno(stdout))) {
++ switch(level) {
++ case ALPM_LOG_ERROR:
++ pm_asprintf(string, "%s%s%s%s", colortab.red, _("error: "), colortab.none, msg);
++ break;
++ case ALPM_LOG_WARNING:
++ pm_asprintf(string, "%s%s%s%s", colortab.yellow, _("warning: "), colortab.none, msg);
++ break;
++ case ALPM_LOG_DEBUG:
++ pm_asprintf(string, "debug: %s", msg);
++ break;
++ case ALPM_LOG_FUNCTION:
++ pm_asprintf(string, "function: %s", msg);
++ break;
++ default:
++ pm_asprintf(string, "%s", msg);
++ break;
++ }
++ } else {
++ switch(level) {
++ case ALPM_LOG_ERROR:
++ pm_asprintf(string, _("error: %s"), msg);
++ break;
++ case ALPM_LOG_WARNING:
++ pm_asprintf(string, _("warning: %s"), msg);
++ break;
++ case ALPM_LOG_DEBUG:
++ pm_asprintf(string, "debug: %s", msg);
++ break;
++ case ALPM_LOG_FUNCTION:
++ pm_asprintf(string, "function: %s", msg);
++ break;
++ default:
++ pm_asprintf(string, "%s", msg);
++ break;
++ }
+ }
+ free(msg);
+
+@@ -1524,10 +1558,10 @@ int pm_vfprintf(FILE *stream, alpm_logle
+ /* print a prefix to the message */
+ switch(level) {
+ case ALPM_LOG_ERROR:
+- fprintf(stream, _("error: "));
++ color_fprintf(stream, COLOR_RED_ALL, _("error: "));
+ break;
+ case ALPM_LOG_WARNING:
+- fprintf(stream, _("warning: "));
++ color_fprintf(stream, COLOR_YELLOW_ALL, _("warning: "));
+ break;
+ case ALPM_LOG_DEBUG:
+ fprintf(stream, "debug: ");
+@@ -1566,4 +1600,310 @@ char *strndup(const char *s, size_t n)
+ }
+ #endif
+
++/* pacman-color */
++
++int _set_color_sequence(const char* name, char* dest)
++{
++ int ret = 0;
++
++ if(strcmp(name, "black") == 0) {
++ strncpy(dest, "\033[0;30m", COLOR_LEN);
++ } else if(strcmp(name, "red") == 0) {
++ strncpy(dest, "\033[0;31m", COLOR_LEN);
++ } else if(strcmp(name, "green") == 0) {
++ strncpy(dest, "\033[0;32m", COLOR_LEN);
++ } else if(strcmp(name, "yellow") == 0) {
++ strncpy(dest, "\033[0;33m", COLOR_LEN);
++ } else if(strcmp(name, "blue") == 0) {
++ strncpy(dest, "\033[0;34m", COLOR_LEN);
++ } else if(strcmp(name, "magenta") == 0) {
++ strncpy(dest, "\033[0;35m", COLOR_LEN);
++ } else if(strcmp(name, "cyan") == 0) {
++ strncpy(dest, "\033[0;36m", COLOR_LEN);
++ } else if(strcmp(name, "white") == 0) {
++ strncpy(dest, "\033[0;37m", COLOR_LEN);
++ } else if(strcmp(name, "gray") == 0) {
++ strncpy(dest, "\033[1;30m", COLOR_LEN);
++ } else if(strcmp(name, "intensive red") == 0) {
++ strncpy(dest, "\033[1;31m", COLOR_LEN);
++ } else if(strcmp(name, "intensive green") == 0) {
++ strncpy(dest, "\033[1;32m", COLOR_LEN);
++ } else if(strcmp(name, "intensive yellow") == 0) {
++ strncpy(dest, "\033[1;33m", COLOR_LEN);
++ } else if(strcmp(name, "intensive blue") == 0) {
++ strncpy(dest, "\033[1;34m", COLOR_LEN);
++ } else if(strcmp(name, "intensive magenta") == 0) {
++ strncpy(dest, "\033[1;35m", COLOR_LEN);
++ } else if(strcmp(name, "intensive cyan") == 0) {
++ strncpy(dest, "\033[1;36m", COLOR_LEN);
++ } else if(strcmp(name, "intensive white") == 0) {
++ strncpy(dest, "\033[1;37m", COLOR_LEN);
++ } else if(strcmp(name, "intensive foreground") == 0) {
++ strncpy(dest, "\033[m\033[1m", COLOR_LEN);
++ } else if(strcmp(name, "none") == 0) {
++ strncpy(dest, "\033[m", COLOR_LEN);
++ } else {
++ ret = 1;
++ }
++ dest[COLOR_LEN] = '\0';
++ return(ret);
++}
++
++void _insert_color(FILE* stream, color_t color)
++{
++ switch(color) {
++ case COLOR_RED:
++ fprintf(stream, colortab.red);
++ break;
++ case COLOR_GREEN:
++ fprintf(stream, colortab.green);
++ break;
++ case COLOR_YELLOW:
++ fprintf(stream, colortab.yellow);
++ break;
++ case COLOR_BLUE:
++ fprintf(stream, colortab.blue);
++ break;
++ case COLOR_MAGENTA:
++ fprintf(stream, colortab.magenta);
++ break;
++ case COLOR_CYAN:
++ fprintf(stream, colortab.cyan);
++ break;
++ case COLOR_WHITE:
++ fprintf(stream, colortab.white);
++ break;
++ case COLOR_NONE:
++ fprintf(stream, colortab.none);
++ break;
++ default:;
++ }
++}
++
++int _parsecolorconfig(colortab_t* colortab, char* file)
++{
++ _set_color_sequence("intensive red", colortab->red);
++ _set_color_sequence("intensive green", colortab->green);
++ _set_color_sequence("intensive yellow", colortab->yellow);
++ _set_color_sequence("intensive blue", colortab->blue);
++ _set_color_sequence("intensive magenta", colortab->magenta);
++ _set_color_sequence("intensive cyan", colortab->cyan);
++ _set_color_sequence("intensive foreground", colortab->white);
++ _set_color_sequence("none", colortab->none);
++
++ FILE* fp = NULL;
++ int linenum = 0;
++ char line[PATH_MAX+1];
++ char* ptr;
++
++ fp = fopen(file, "r");
++ if(fp == NULL) {
++ pm_printf(ALPM_LOG_ERROR, _("config file %s could not be read.\n"), file);
++ return 1;
++ }
++ while(fgets(line, PATH_MAX, fp)) {
++ linenum++;
++ strtrim(line);
++
++ if(strlen(line) == 0 || line[0] == '#') {
++ continue;
++ }
++ if((ptr = strchr(line, '#'))) {
++ *ptr = '\0';
++ }
++
++ char* key = line;
++ ptr = line;
++ strsep(&ptr, "=");
++ strtrim(key);
++ strtrim(ptr);
++
++ if(key == NULL) {
++ pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: syntax error in config file- missing key.\n"),
++ file, linenum);
++ return 1;
++ }
++ if(strcmp(key, "Red") == 0) {
++ if(_set_color_sequence(ptr, colortab->red)) {
++ pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"),
++ file, linenum, ptr);
++ }
++ } else if(strcmp(key, "Green") == 0) {
++ if(_set_color_sequence(ptr, colortab->green)) {
++ pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"),
++ file, linenum, ptr);
++ }
++ } else if(strcmp(key, "Yellow") == 0) {
++ if(_set_color_sequence(ptr, colortab->yellow)) {
++ pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"),
++ file, linenum, ptr);
++ }
++ } else if(strcmp(key, "Blue") == 0) {
++ if(_set_color_sequence(ptr, colortab->blue)) {
++ pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"),
++ file, linenum, ptr);
++ }
++ } else if(strcmp(key, "Magenta") == 0) {
++ if(_set_color_sequence(ptr, colortab->magenta)) {
++ pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"),
++ file, linenum, ptr);
++ }
++ } else if(strcmp(key, "Cyan") == 0) {
++ if(_set_color_sequence(ptr, colortab->cyan)) {
++ pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"),
++ file, linenum, ptr);
++ }
++ } else if(strcmp(key, "White") == 0) {
++ if(_set_color_sequence(ptr, colortab->white)) {
++ pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"),
++ file, linenum, ptr);
++ }
++ } else {
++ pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: directive '%s' not recognized.\n"),
++ file, linenum, key);
++ return(1);
++ }
++ }
++ return(0);
++}
++
++int parsecolorconfig()
++{
++ return(_parsecolorconfig(&colortab, "/etc/pacman.d/color.conf"));
++}
++
++int color_vfprintf(FILE* stream, const colordata_t* colors, const char* format, va_list args)
++{
++ int ret = 0;
++
++ if(isatty(fileno(stream)) && colors) {
++ char* msg = NULL;
++ ret = vasprintf(&msg, format, args);
++ if(msg == NULL) {
++ return(ret);
++ }
++
++ const colordata_t* colorpos = colors;
++ color_t colorlast = COLOR_NONE;
++ int len = strlen(msg) + 1;
++ wchar_t* wcstr = calloc(len, sizeof(wchar_t));
++ len = mbstowcs(wcstr, msg, len);
++ free(msg);
++ const wchar_t *strpos = wcstr;
++
++ while(*strpos) {
++ if(colorpos->color != COLOR_END &&
++ ((colorpos->separator == SEP_ANY) ||
++ (colorpos->separator == SEP_LINE && *strpos == L'\n') ||
++ (colorpos->separator == SEP_COLON && (*strpos == L':' || *strpos == L':')))) {
++ _insert_color(stream, colorpos->color);
++ colorlast = colorpos->color;
++ colorpos++;
++ }
++ fprintf(stream, "%lc", (wint_t)*strpos);
++ strpos++;
++ }
++ free(wcstr);
++
++ if(colorlast != COLOR_NONE) {
++ _insert_color(stream, COLOR_NONE);
++ }
++ } else {
++ ret = vfprintf(stream, format, args);
++ }
++ return(ret);
++}
++
++int color_fprintf(FILE* stream, const colordata_t* colors, const char* format, ...)
++{
++ int ret;
++ va_list args;
++ va_start(args, format);
++ ret = color_vfprintf(stream, colors, format, args);
++ va_end(args);
++ return(ret);
++}
++
++int color_printf(const colordata_t* colors, const char* format, ...)
++{
++ int ret;
++ va_list args;
++ va_start(args, format);
++ ret = color_vfprintf(stdout, colors, format, args);
++ va_end(args);
++ return(ret);
++}
++
++void color_string_display(const colordata_t* colors_title, const char* title, const colordata_t* colors_string, const char* string)
++{
++ if(title) {
++ color_printf(colors_title, "%s ", title);
++ }
++ if(string == NULL || string[0] == '\0') {
++ printf(_("None"));
++ } else {
++ color_printf(colors_string, "%s", string);
++ }
++ printf("\n");
++}
++
++const colordata_t COLOR_WHITE_ALL[] = {
++ { SEP_ANY, COLOR_WHITE },
++ { SEP_LINE, COLOR_NONE },
++ { SEP_ANY, COLOR_END } };
++
++const colordata_t COLOR_GREEN_ALL[] = {
++ { SEP_ANY, COLOR_GREEN },
++ { SEP_LINE, COLOR_NONE },
++ { SEP_ANY, COLOR_END } };
++
++const colordata_t COLOR_RED_ALL[] = {
++ { SEP_ANY, COLOR_RED },
++ { SEP_LINE, COLOR_NONE },
++ { SEP_ANY, COLOR_END } };
++
++const colordata_t COLOR_BLUE_ALL[] = {
++ { SEP_ANY, COLOR_BLUE },
++ { SEP_LINE, COLOR_NONE },
++ { SEP_ANY, COLOR_END } };
++
++const colordata_t COLOR_YELLOW_ALL[] = {
++ { SEP_ANY, COLOR_YELLOW },
++ { SEP_LINE, COLOR_NONE },
++ { SEP_ANY, COLOR_END } };
++
++const colordata_t COLOR_MAGENTA_ALL[] = {
++ { SEP_ANY, COLOR_MAGENTA },
++ { SEP_LINE, COLOR_NONE },
++ { SEP_ANY, COLOR_END } };
++
++const colordata_t COLOR_CYAN_ALL[] = {
++ { SEP_ANY, COLOR_CYAN },
++ { SEP_LINE, COLOR_NONE },
++ { SEP_ANY, COLOR_END } };
++
++const colordata_t COLOR_DOUBLECOLON[] = {
++ { SEP_ANY, COLOR_BLUE },
++ { SEP_ANY, COLOR_SAME },
++ { SEP_ANY, COLOR_WHITE },
++ { SEP_LINE, COLOR_NONE },
++ { SEP_ANY, COLOR_END } };
++
++const colordata_t COLOR_DOUBLECOLON2[] = {
++ { SEP_ANY, COLOR_BLUE },
++ { SEP_ANY, COLOR_SAME },
++ { SEP_ANY, COLOR_WHITE },
++ { SEP_LINE, COLOR_NONE },
++ { SEP_ANY, COLOR_BLUE },
++ { SEP_ANY, COLOR_SAME },
++ { SEP_ANY, COLOR_WHITE },
++ { SEP_LINE, COLOR_NONE },
++ { SEP_ANY, COLOR_END } };
++
++const colordata_t COLOR_WHITE_COLON[] = {
++ { SEP_ANY, COLOR_WHITE },
++ { SEP_COLON, COLOR_SAME },
++ { SEP_ANY, COLOR_NONE },
++ { SEP_ANY, COLOR_END } };
++
+ /* vim: set ts=2 sw=2 noet: */
+diff -up -Npaur a/src/pacman/util.h b/src/pacman/util.h
+--- a/src/pacman/util.h 2012-02-03 16:56:16.000000000 +0200
++++ b/src/pacman/util.h 2012-07-20 21:48:20.271827634 +0300
+@@ -45,6 +45,48 @@ typedef struct _pm_target_t {
+ int is_explicit;
+ } pm_target_t;
+
++/* pacman-color */
++typedef enum _separator_t {
++ SEP_ANY = 0,
++ SEP_LINE,
++ SEP_COLON,
++} separator_t;
++
++typedef enum _color_t {
++ COLOR_END = 0,
++ COLOR_SAME,
++ COLOR_RED,
++ COLOR_GREEN,
++ COLOR_YELLOW,
++ COLOR_BLUE,
++ COLOR_MAGENTA,
++ COLOR_CYAN,
++ COLOR_WHITE,
++ COLOR_NONE,
++} color_t;
++
++typedef struct _colordata_t {
++ separator_t separator;
++ color_t color;
++} colordata_t;
++
++extern const colordata_t COLOR_WHITE_ALL[];
++extern const colordata_t COLOR_GREEN_ALL[];
++extern const colordata_t COLOR_RED_ALL[];
++extern const colordata_t COLOR_BLUE_ALL[];
++extern const colordata_t COLOR_YELLOW_ALL[];
++extern const colordata_t COLOR_MAGENTA_ALL[];
++extern const colordata_t COLOR_CYAN_ALL[];
++extern const colordata_t COLOR_DOUBLECOLON[];
++extern const colordata_t COLOR_DOUBLECOLON2[];
++extern const colordata_t COLOR_WHITE_COLON[];
++
++int parsecolorconfig();
++int color_fprintf(FILE* stream, const colordata_t* colors, const char* format, ...) __attribute__((format(printf,3,4)));
++int color_printf(const colordata_t* colors, const char* format, ...) __attribute__((format(printf,2,3)));
++int color_vfprintf(FILE* stream, const colordata_t* colors, const char* format, va_list args) __attribute__((format(printf,3,0)));
++void color_string_display(const colordata_t* colors_title, const char* title, const colordata_t* colors_string, const char* string);
++
+ void trans_init_error(void);
+ int trans_init(alpm_transflag_t flags, int check_valid);
+ int trans_release(void);
+@@ -58,12 +100,12 @@ void indentprint(const char *str, size_t
+ char *strtrim(char *str);
+ char *strreplace(const char *str, const char *needle, const char *replace);
+ alpm_list_t *strsplit(const char *str, const char splitchar);
+-void string_display(const char *title, const char *string);
++void string_display(const colordata_t *colors_title, const char *title, const char *string);
+ double humanize_size(off_t bytes, const char target_unit, int precision,
+ const char **label);
+ int table_display(const char *title, const alpm_list_t *header, const alpm_list_t *rows);
+-void list_display(const char *title, const alpm_list_t *list);
+-void list_display_linebreak(const char *title, const alpm_list_t *list);
++void list_display(const colordata_t *colors_title, const char *title, const alpm_list_t *list);
++void list_display_linebreak(const colordata_t *colors_title, const char *title, const alpm_list_t *list);
+ void signature_display(const char *title, alpm_siglist_t *siglist);
+ void display_targets(void);
+ int str_cmp(const void *s1, const void *s2);
+@@ -73,8 +115,8 @@ void print_packages(const alpm_list_t *p
+ void select_display(const alpm_list_t *pkglist);
+ int select_question(int count);
+ int multiselect_question(char *array, int count);
+-int yesno(char *fmt, ...);
+-int noyes(char *fmt, ...);
++int yesno(const colordata_t *colors, char *fmt, ...);
++int noyes(const colordata_t *colors, char *fmt, ...);
+
+ int pm_printf(alpm_loglevel_t level, const char *format, ...) __attribute__((format(printf,2,3)));
+ int pm_asprintf(char **string, const char *format, ...);