[gnome-color-manager] Add a pkexec helper to install an ICC profile system-wide



commit 89d886ffdbee39defde4d663a918070a48a5e2e6
Author: Richard Hughes <richard hughsie com>
Date:   Fri Jan 1 12:37:27 2010 +0000

    Add a pkexec helper to install an ICC profile system-wide

 configure.ac                        |    4 +-
 contrib/gnome-color-manager.spec.in |    5 +
 po/POTFILES.in                      |    1 +
 src/.gitignore                      |    1 +
 src/Makefile.am                     |   18 ++++
 src/gcm-install-system-wide.c       |  156 +++++++++++++++++++++++++++++++++++
 6 files changed, 184 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 42330bb..7e103da 100644
--- a/configure.ac
+++ b/configure.ac
@@ -112,7 +112,7 @@ DBUS_GLIB_REQUIRED=0.73
 dnl ---------------------------------------------------------------------------
 dnl - Check library dependencies
 dnl ---------------------------------------------------------------------------
-PKG_CHECK_MODULES(GLIB, glib-2.0 >= $GLIB_REQUIRED gobject-2.0 gthread-2.0)
+PKG_CHECK_MODULES(GLIB, glib-2.0 >= $GLIB_REQUIRED gobject-2.0 gthread-2.0 gio-2.0)
 AC_SUBST(GLIB_CFLAGS)
 AC_SUBST(GLIB_LIBS)
 
@@ -216,6 +216,8 @@ if test x$enable_tests = xyes; then
 	AC_DEFINE(EGG_BUILD_TESTS,1,[Build test code])
 fi
 
+AC_SUBST(GCM_SYSTEM_PROFILES_DIR, "\$(localstatedir)/lib/color")
+
 dnl ---------------------------------------------------------------------------
 dnl - Makefiles, etc.
 dnl ---------------------------------------------------------------------------
diff --git a/contrib/gnome-color-manager.spec.in b/contrib/gnome-color-manager.spec.in
index b358eff..be05f33 100644
--- a/contrib/gnome-color-manager.spec.in
+++ b/contrib/gnome-color-manager.spec.in
@@ -24,6 +24,7 @@ Requires:  dbus-x11
 Requires:  udev
 Requires:  vte
 Requires:  lcms
+Requires:  polkit
 Requires:  PackageKit
 Requires:  shared-color-profiles
 Requires(post):   scrollkeeper
@@ -125,6 +126,10 @@ update-mime-database %{_datadir}/mime &> /dev/null || :
 %{_datadir}/applications/gcm-import.desktop
 %{_sysconfdir}/xdg/autostart/*.desktop
 %{_datadir}/dbus-1/services/org.gnome.ColorManager.service
+%{_sbindir}/gcm-install-system-wide
+%{_datadir}/polkit-1/actions/org.gnome.color.policy
+# this is probably better in a shared package
+%dir %{_localstatedir}/lib/color
 
 %changelog
 * #LONGDATE# Richard Hughes <richard hughsie com> #VERSION#-0.#BUILD##ALPHATAG#
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 797a42e..11aedad 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -10,6 +10,7 @@ src/gcm-calibrate-manual.c
 src/gcm-client.c
 src/gcm-dump-edid.c
 src/gcm-dump-profile.c
+src/gcm-install-system-wide.c
 src/gcm-import.c
 src/gcm-inspect.c
 src/gcm-prefs.c
diff --git a/src/.gitignore b/src/.gitignore
index 92146d9..293e34e 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -10,5 +10,6 @@ gcm-session
 gcm-dump-edid
 gcm-dump-profile
 gcm-self-test
+gcm-install-system-wide
 org.gnome.ColorManager.h
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 92430aa..441d5a6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,6 +15,7 @@ INCLUDES =						\
 	-DSYSCONFDIR=\""$(sysconfdir)"\" 		\
 	-DVERSION="\"$(VERSION)\"" 			\
 	-DLOCALEDIR=\""$(localedir)"\"			\
+	-DGCM_SYSTEM_PROFILES_DIR="\"$(GCM_SYSTEM_PROFILES_DIR)"\" \
 	-DGCM_DATA=\"$(pkgdatadir)\"
 
 noinst_LIBRARIES = libgcmshared.a
@@ -57,6 +58,9 @@ libgcmshared_a_SOURCES =				\
 libgcmshared_a_CFLAGS =					\
 	$(WARNINGFLAGS_C)
 
+sbin_PROGRAMS =						\
+	gcm-install-system-wide
+
 bin_PROGRAMS =						\
 	gcm-inspect					\
 	gcm-dump-profile				\
@@ -66,6 +70,15 @@ bin_PROGRAMS =						\
 	gcm-session					\
 	gcm-import
 
+gcm_install_system_wide_SOURCES =			\
+	gcm-install-system-wide.c
+
+gcm_install_system_wide_LDADD =				\
+	$(GLIB_LIBS)
+
+gcm_install_system_wide_CFLAGS =			\
+	$(WARNINGFLAGS_C)
+
 gcm_dump_edid_SOURCES =					\
 	gcm-dump-edid.c
 
@@ -250,6 +263,11 @@ org.gnome.ColorManager.h: org.gnome.ColorManager.xml
 		--output=org.gnome.ColorManager.h	\
 		$(srcdir)/org.gnome.ColorManager.xml
 
+install-data-hook:
+	if test -w $(DESTDIR)$(prefix)/; then \
+		mkdir -p $(DESTDIR)$(GCM_SYSTEM_PROFILES_DIR); \
+	fi
+
 clean-local:
 	rm -f *~
 
diff --git a/src/gcm-install-system-wide.c b/src/gcm-install-system-wide.c
new file mode 100644
index 0000000..50a331f
--- /dev/null
+++ b/src/gcm-install-system-wide.c
@@ -0,0 +1,156 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <locale.h>
+
+#define GCM_INSTALL_SYSTEM_WIDE_EXIT_CODE_SUCCESS			0
+#define GCM_INSTALL_SYSTEM_WIDE_EXIT_CODE_FAILED			1
+#define GCM_INSTALL_SYSTEM_WIDE_EXIT_CODE_ARGUMENTS_INVALID		3
+#define GCM_INSTALL_SYSTEM_WIDE_EXIT_CODE_CONTENT_TYPE_INVALID		4
+#define GCM_INSTALL_SYSTEM_WIDE_EXIT_CODE_FAILED_TO_COPY		5
+
+/**
+ * main:
+ **/
+gint
+main (gint argc, gchar *argv[])
+{
+	gchar **filenames = NULL;
+	gchar *id = NULL;
+	GOptionContext *context;
+	gint uid;
+	gint euid;
+	guint retval = 0;
+	gchar *dest = NULL;
+	GFile *file = NULL;
+	GFile *file_dest = NULL;
+	GFileInfo *info = NULL;
+	const gchar *type;
+	GError *error = NULL;
+	gboolean ret = FALSE;
+
+	const GOptionEntry options[] = {
+		{ "id", '\0', 0, G_OPTION_ARG_STRING, &id,
+		   /* command line argument, the ID of the device */
+		  _("Device ID, e.g. xrandr_ibm_france_ltn154p2_l05"), NULL },
+		{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames,
+		  /* TRANSLATORS: command line option: a list of files to install */
+		  _("ICC profile to install"), NULL },
+		{ NULL}
+	};
+
+	/* setup translations */
+	setlocale (LC_ALL, "");
+	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+	textdomain (GETTEXT_PACKAGE);
+
+	/* setup type system */
+	g_type_init ();
+
+	context = g_option_context_new (NULL);
+	/* TRANSLATORS: tool that is used when copying profiles system-wide */
+	g_option_context_set_summary (context, _("GNOME Color Manager ICC profile system-wide installer"));
+	g_option_context_add_main_entries (context, options, NULL);
+	g_option_context_parse (context, &argc, &argv, NULL);
+	g_option_context_free (context);
+
+	/* no input */
+	if (filenames == NULL || g_strv_length (filenames) != 1) {
+		/* TRANSLATORS: user did not specify a valid filename */
+		g_print ("%s\n", _("You need to specify exactly one ICC profile filename"));
+		retval = GCM_INSTALL_SYSTEM_WIDE_EXIT_CODE_ARGUMENTS_INVALID;
+		goto out;
+	}
+
+	/* no id */
+	if (id == NULL) {
+		/* TRANSLATORS: user did not specify a valid device ID */
+		g_print ("%s\n", _("You need to specify exactly one device ID"));
+		retval = GCM_INSTALL_SYSTEM_WIDE_EXIT_CODE_ARGUMENTS_INVALID;
+		goto out;
+	}
+
+	/* get calling process */
+	uid = getuid ();
+	euid = geteuid ();
+	if (uid != 0 || euid != 0) {
+		/* TRANSLATORS: only able to install profiles as root */
+		g_print ("%s\n", _("This program can only be used by the root user"));
+		retval = GCM_INSTALL_SYSTEM_WIDE_EXIT_CODE_ARGUMENTS_INVALID;
+		goto out;
+	}
+
+	/* get content type for file */
+	file = g_file_new_for_path (filenames[0]);
+	info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, NULL, &error);
+	if (info == NULL) {
+		/* TRANSLATORS: error details */
+		g_print ("%s: %s\n", _("Failed to get content type"), error->message);
+		g_error_free (error);
+		retval = GCM_INSTALL_SYSTEM_WIDE_EXIT_CODE_CONTENT_TYPE_INVALID;
+		goto out;
+	}
+
+	/* check is correct type */
+	type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
+	if (g_strcmp0 (type, "application/vnd.iccprofile") != 0) {
+		/* TRANSLATORS: the content type is the detected type of file */
+		g_print ("%s: %s\n", _("Content type was incorrect"), type);
+		retval = GCM_INSTALL_SYSTEM_WIDE_EXIT_CODE_CONTENT_TYPE_INVALID;
+		goto out;
+	}
+
+	/* get new location */
+	dest = g_strdup_printf ("%s/%s.icc", GCM_SYSTEM_PROFILES_DIR, id);
+	file_dest = g_file_new_for_path (dest);
+
+	/* do the copy */
+	ret = g_file_copy (file, file_dest, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error);
+	if (!ret) {
+		/* TRANSLATORS: error details */
+		g_print ("%s: %s\n", _("Failed to copy"), error->message);
+		g_error_free (error);
+		retval = GCM_INSTALL_SYSTEM_WIDE_EXIT_CODE_FAILED_TO_COPY;
+		goto out;
+	}
+
+	/* success */
+	retval = GCM_INSTALL_SYSTEM_WIDE_EXIT_CODE_SUCCESS;
+out:
+	if (info != NULL)
+		g_object_unref (info);
+	if (file != NULL)
+		g_object_unref (file);
+	if (file_dest != NULL)
+		g_object_unref (file_dest);
+	g_strfreev (filenames);
+	g_free (id);
+	return retval;
+}
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]