summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorWilliam Jon McCann <mccann@jhu.edu>2007-03-21 17:08:39 +0000
committerWilliam Jon McCann <mccann@src.gnome.org>2007-03-21 17:08:39 +0000
commitaae779a0c49b2ed689a1b44298c6b0d2d4298c08 (patch)
tree629111aba5bfddee4537cf1ed6f95209ac8c9c91 /common
parent94b410c4a4f36cd04f1a9ee32d82806e1ba2b573 (diff)
downloadgdm-aae779a0c49b2ed689a1b44298c6b0d2d4298c08.tar.gz
Added new files missed from commit for #355425
2007-03-21 William Jon McCann <mccann@jhu.edu> * common/Makefile.am: * common/gdm-common-config.c: (gdm_common_config_parse_key_string), (gdm_common_config_load), (gdm_common_config_save), (gdm_common_config_get_int), (gdm_common_config_get_translated_string), (gdm_common_config_get_string), (gdm_common_config_get_boolean), (gdm_common_config_set_string), (gdm_common_config_set_boolean), (gdm_common_config_set_int), (gdm_common_config_remove_key): * common/gdm-common-config.h: * common/gdm-common.c: (ve_clearenv), (ve_first_word), (ve_first_word_executable), (ve_get_first_working_command), (ve_rest), (ve_bool_equal), (ve_is_string_in_list), (ve_is_string_in_list_case_no_locale), (ve_find_file_simple), (ve_locale_to_utf8), (ve_locale_from_utf8), (ve_filename_to_utf8), (ve_filename_from_utf8), (ve_strftime), (ve_waitpid_no_signal), (ve_locale_exists), (ve_find_prog_in_path), (ve_is_prog_in_path), (ve_shell_quote_filename): * common/gdm-common.h: * common/ve-signal.c: (ve_signal_prepare), (ve_signal_check), (ve_signal_dispatch), (ve_signal_add), (ve_signal_add_full), (ve_signal_notify), (ve_signal_was_notified), (ve_signal_unnotify): * common/ve-signal.h: Added new files missed from commit for #355425 svn path=/trunk/; revision=4696
Diffstat (limited to 'common')
-rw-r--r--common/Makefile.am30
-rw-r--r--common/gdm-common-config.c398
-rw-r--r--common/gdm-common-config.h71
-rw-r--r--common/gdm-common.c374
-rw-r--r--common/gdm-common.h102
-rw-r--r--common/ve-signal.c160
-rw-r--r--common/ve-signal.h46
7 files changed, 1181 insertions, 0 deletions
diff --git a/common/Makefile.am b/common/Makefile.am
new file mode 100644
index 00000000..63f670e9
--- /dev/null
+++ b/common/Makefile.am
@@ -0,0 +1,30 @@
+## Process this file with automake to produce Makefile.in
+
+NULL =
+
+INCLUDES = \
+ -I. \
+ -I.. \
+ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
+ $(GLIB_CFLAGS)
+
+noinst_LIBRARIES = \
+ libgdmcommon.a \
+ $(null)
+
+libgdmcommon_a_SOURCES = \
+ gdm-common.h \
+ gdm-common.c \
+ gdm-common-config.h \
+ gdm-common-config.c \
+ ve-signal.h \
+ ve-signal.c \
+ $(NULL)
+
+libgdmcommon_ui_a_SOURCES = \
+ $(libgdmcommon_a_SOURCES) \
+ glade-helper.c \
+ glade-helper.h \
+ gdm-common-ui.c \
+ gdm-common-ui.h \
+ $(NULL)
diff --git a/common/gdm-common-config.c b/common/gdm-common-config.c
new file mode 100644
index 00000000..42f06777
--- /dev/null
+++ b/common/gdm-common-config.c
@@ -0,0 +1,398 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <syslog.h>
+
+#include <glib.h>
+
+#include "gdm-common-config.h"
+
+gboolean
+gdm_common_config_parse_key_string (const char *keystring,
+ char **group,
+ char **key,
+ char **value)
+{
+ char **split1;
+ char **split2;
+ char *g;
+ char *k;
+ char *v;
+ gboolean ret;
+
+ ret = FALSE;
+ g = k = v = NULL;
+ split1 = split2 = NULL;
+
+ split1 = g_strsplit (keystring, "/", 2);
+ if (split1 == NULL) {
+ goto out;
+ }
+
+ g = split1 [0];
+
+ split2 = g_strsplit (split1 [1], "=", 2);
+ if (split2 == NULL) {
+ k = split1 [1];
+ } else {
+ k = split2 [0];
+ v = split2 [1];
+ }
+
+ ret = TRUE;
+ out:
+ if (group != NULL) {
+ *group = g_strdup (g);
+ }
+ if (key != NULL) {
+ *key = g_strdup (k);
+ }
+ if (value != NULL) {
+ *value = g_strdup (v);
+ }
+
+ g_strfreev (split1);
+ g_strfreev (split2);
+
+ return ret;
+}
+
+GKeyFile *
+gdm_common_config_load (const char *filename,
+ GError **error)
+{
+ GKeyFile *config;
+ GError *local_error;
+ gboolean res;
+
+ config = g_key_file_new ();
+
+ local_error = NULL;
+ res = g_key_file_load_from_file (config,
+ filename,
+ G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
+ &local_error);
+ if (! res) {
+ g_propagate_error (error, local_error);
+ g_key_file_free (config);
+ return NULL;
+ }
+
+ return config;
+}
+
+gboolean
+gdm_common_config_save (GKeyFile *config,
+ const char *filename,
+ GError **error)
+{
+ GError *local_error;
+ gboolean res;
+ char *contents;
+ gsize length;
+
+ local_error = NULL;
+ contents = g_key_file_to_data (config, &length, &local_error);
+ if (local_error != NULL) {
+ g_propagate_error (error, local_error);
+ return FALSE;
+ }
+
+ local_error = NULL;
+ res = g_file_set_contents (filename,
+ contents,
+ length,
+ &local_error);
+ if (local_error != NULL) {
+ g_propagate_error (error, local_error);
+ g_free (contents);
+ return FALSE;
+ }
+
+ g_free (contents);
+ return TRUE;
+}
+
+gboolean
+gdm_common_config_get_int (GKeyFile *config,
+ const char *keystring,
+ int *value,
+ GError **error)
+{
+ char *group;
+ char *key;
+ char *default_value;
+ int val;
+ GError *local_error;
+
+ group = key = default_value = NULL;
+ if (! gdm_common_config_parse_key_string (keystring, &group, &key, &default_value))
+ return FALSE;
+
+ local_error = NULL;
+ val = g_key_file_get_integer (config,
+ group,
+ key,
+ &local_error);
+ if (local_error != NULL) {
+ /* use the default */
+ if (default_value != NULL) {
+ val = atoi (default_value);
+ } else {
+ val = 0;
+ }
+ g_propagate_error (error, local_error);
+ }
+
+ *value = val;
+
+ g_free (key);
+ g_free (group);
+ g_free (default_value);
+
+ return TRUE;
+}
+
+gboolean
+gdm_common_config_get_translated_string (GKeyFile *config,
+ const char *keystring,
+ char **value,
+ GError **error)
+{
+ char *group;
+ char *key;
+ char *default_value;
+ char *val;
+ const char * const *langs;
+ int i;
+
+ val = NULL;
+
+ group = key = default_value = NULL;
+ if (! gdm_common_config_parse_key_string (keystring, &group, &key, &default_value))
+ return FALSE;
+
+ langs = g_get_language_names ();
+
+ for (i = 0; langs[i] != NULL; i++) {
+ const char *locale;
+ locale = langs[i];
+
+ val = g_key_file_get_locale_string (config,
+ group,
+ key,
+ locale,
+ NULL);
+ if (val != NULL) {
+ break;
+ }
+ }
+
+ if (val == NULL) {
+ /* use the default */
+ val = g_strdup (default_value);
+ }
+
+ *value = val;
+
+ g_free (key);
+ g_free (group);
+ g_free (default_value);
+
+ return TRUE;
+}
+
+gboolean
+gdm_common_config_get_string (GKeyFile *config,
+ const char *keystring,
+ char **value,
+ GError **error)
+{
+ char *group;
+ char *key;
+ char *default_value;
+ char *val;
+ GError *local_error;
+
+ group = key = default_value = NULL;
+ if (! gdm_common_config_parse_key_string (keystring, &group, &key, &default_value)) {
+ g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE, "Unable to parse key: %s", keystring);
+ return FALSE;
+ }
+
+ local_error = NULL;
+ val = g_key_file_get_string (config,
+ group,
+ key,
+ &local_error);
+ if (local_error != NULL) {
+ /* use the default */
+ val = g_strdup (default_value);
+ g_propagate_error (error, local_error);
+ }
+
+ *value = val;
+
+ g_free (key);
+ g_free (group);
+ g_free (default_value);
+
+ return TRUE;
+}
+
+gboolean
+gdm_common_config_get_boolean (GKeyFile *config,
+ const char *keystring,
+ gboolean *value,
+ GError **error)
+{
+ char *group;
+ char *key;
+ char *default_value;
+ gboolean val;
+ GError *local_error;
+
+ group = key = default_value = NULL;
+ if (! gdm_common_config_parse_key_string (keystring, &group, &key, &default_value))
+ return FALSE;
+
+ local_error = NULL;
+ val = g_key_file_get_boolean (config,
+ group,
+ key,
+ &local_error);
+ if (local_error != NULL) {
+ /* use the default */
+ if (default_value != NULL &&
+ (default_value[0] == 'T' ||
+ default_value[0] == 't' ||
+ default_value[0] == 'Y' ||
+ default_value[0] == 'y' ||
+ atoi (default_value) != 0)) {
+ val = TRUE;
+ } else {
+ val = FALSE;
+ }
+ g_propagate_error (error, local_error);
+ }
+
+ *value = val;
+
+ g_free (key);
+ g_free (group);
+ g_free (default_value);
+
+ return TRUE;
+}
+
+void
+gdm_common_config_set_string (GKeyFile *config,
+ const char *keystring,
+ const char *value)
+{
+ char *group;
+ char *key;
+ char *default_value;
+
+ group = key = default_value = NULL;
+ if (! gdm_common_config_parse_key_string (keystring, &group, &key, &default_value)) {
+ return;
+ }
+
+ g_key_file_set_string (config, group, key, value);
+
+ g_free (key);
+ g_free (group);
+ g_free (default_value);
+}
+
+void
+gdm_common_config_set_boolean (GKeyFile *config,
+ const char *keystring,
+ gboolean value)
+{
+ char *group;
+ char *key;
+ char *default_value;
+
+ group = key = default_value = NULL;
+ if (! gdm_common_config_parse_key_string (keystring, &group, &key, &default_value)) {
+ return;
+ }
+
+ g_key_file_set_boolean (config, group, key, value);
+
+ g_free (key);
+ g_free (group);
+ g_free (default_value);
+}
+
+void
+gdm_common_config_set_int (GKeyFile *config,
+ const char *keystring,
+ int value)
+{
+ char *group;
+ char *key;
+ char *default_value;
+
+ group = key = default_value = NULL;
+ if (! gdm_common_config_parse_key_string (keystring, &group, &key, &default_value)) {
+ return;
+ }
+
+ g_key_file_set_integer (config, group, key, value);
+
+ g_free (key);
+ g_free (group);
+ g_free (default_value);
+}
+
+void
+gdm_common_config_remove_key (GKeyFile *config,
+ const char *keystring,
+ GError **error)
+{
+ char *group;
+ char *key;
+ char *default_value;
+ GError *local_error;
+
+ group = key = default_value = NULL;
+ if (! gdm_common_config_parse_key_string (keystring, &group, &key, &default_value)) {
+ return;
+ }
+
+ local_error = NULL;
+ g_key_file_remove_key (config, group, key, &local_error);
+ if (local_error != NULL) {
+ g_propagate_error (error, local_error);
+ }
+
+ g_free (key);
+ g_free (group);
+ g_free (default_value);
+}
diff --git a/common/gdm-common-config.h b/common/gdm-common-config.h
new file mode 100644
index 00000000..1243ac81
--- /dev/null
+++ b/common/gdm-common-config.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GDM_COMMON_CONFIG_H
+#define _GDM_COMMON_CONFIG_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+GKeyFile * gdm_common_config_load (const char *filename,
+ GError **error);
+gboolean gdm_common_config_save (GKeyFile *config,
+ const char *filename,
+ GError **error);
+
+gboolean gdm_common_config_get_string (GKeyFile *config,
+ const char *keystring,
+ char **value,
+ GError **error);
+gboolean gdm_common_config_get_translated_string (GKeyFile *config,
+ const char *keystring,
+ char **value,
+ GError **error);
+gboolean gdm_common_config_get_int (GKeyFile *config,
+ const char *keystring,
+ int *value,
+ GError **error);
+gboolean gdm_common_config_get_boolean (GKeyFile *config,
+ const char *keystring,
+ gboolean *value,
+ GError **error);
+gboolean gdm_common_config_parse_key_string (const char *keystring,
+ char **group,
+ char **key,
+ char **value);
+
+void gdm_common_config_set_string (GKeyFile *config,
+ const char *keystring,
+ const char *value);
+void gdm_common_config_set_boolean (GKeyFile *config,
+ const char *keystring,
+ gboolean value);
+void gdm_common_config_set_int (GKeyFile *config,
+ const char *keystring,
+ int value);
+
+void gdm_common_config_remove_key (GKeyFile *config,
+ const char *keystring,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* _GDM_COMMON_CONFIG_H */
diff --git a/common/gdm-common.c b/common/gdm-common.c
new file mode 100644
index 00000000..ad4b58a3
--- /dev/null
+++ b/common/gdm-common.c
@@ -0,0 +1,374 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * (c) 2000 Eazel, Inc.
+ * (c) 2001,2002 George Lebl
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <locale.h>
+
+#ifdef HAVE_CRT_EXTERNS_H
+#include <crt_externs.h>
+#endif
+
+#include "gdm-common.h"
+
+/**
+ * ve_clearenv:
+ *
+ * Description: Clears out the environment completely.
+ * In case there is no native implementation of clearenv,
+ * this could cause leaks depending on the implementation
+ * of environment.
+ *
+ **/
+void
+ve_clearenv (void)
+{
+#ifdef HAVE_CLEARENV
+ clearenv ();
+#else
+
+#ifdef HAVE__NSGETENVIRON
+#define environ (*_NSGetEnviron())
+#else
+ extern char **environ;
+#endif
+
+ if (environ != NULL)
+ environ[0] = NULL;
+#endif
+}
+
+char *
+ve_first_word (const char *s)
+{
+ int argc;
+ char **argv;
+ char *ret;
+
+ if (s == NULL)
+ return NULL;
+
+ if ( ! g_shell_parse_argv (s, &argc, &argv, NULL)) {
+ char *p;
+ ret = g_strdup (s);
+ p = strchr (ret, ' ');
+ if (p != NULL)
+ *p = '\0';
+ return ret;
+ }
+
+ ret = g_strdup (argv[0]);
+
+ g_strfreev (argv);
+
+ return ret;
+}
+
+gboolean
+ve_first_word_executable (const char *s, gboolean only_existance)
+{
+ char *bin = ve_first_word (s);
+ if (bin == NULL)
+ return FALSE;
+ if (g_access (bin, only_existance ? F_OK : X_OK) == 0) {
+ g_free (bin);
+ return TRUE;
+ } else {
+ g_free (bin);
+ return FALSE;
+ }
+}
+
+char *
+ve_get_first_working_command (const char *list,
+ gboolean only_existance)
+{
+ int i;
+ char **vector;
+ char *ret = NULL;
+
+ if (list == NULL)
+ return NULL;
+
+ vector = g_strsplit (list, ";", -1);
+ for (i = 0; vector[i] != NULL; i++) {
+ if (ve_first_word_executable (vector[i],
+ only_existance)) {
+ ret = g_strdup (vector[i]);
+ break;
+ }
+ }
+ g_strfreev (vector);
+ return ret;
+}
+
+char *
+ve_rest (const char *s)
+{
+ const char *p;
+ gboolean single_quot = FALSE;
+ gboolean double_quot = FALSE;
+ gboolean escape = FALSE;
+
+ if (s == NULL)
+ return NULL;
+
+ for (p = s; *p != '\0'; p++) {
+ if (single_quot) {
+ if (*p == '\'') {
+ single_quot = FALSE;
+ }
+ } else if (escape) {
+ escape = FALSE;
+ } else if (double_quot) {
+ if (*p == '"') {
+ double_quot = FALSE;
+ } else if (*p == '\\') {
+ escape = TRUE;
+ }
+ } else if (*p == '\'') {
+ single_quot = TRUE;
+ } else if (*p == '"') {
+ double_quot = TRUE;
+ } else if (*p == '\\') {
+ escape = TRUE;
+ } else if (*p == ' ' || *p == '\t') {
+ while (*p == ' ' || *p == '\t')
+ p++;
+ return g_strdup (p);
+ }
+ }
+
+ return NULL;
+}
+
+gboolean
+ve_bool_equal (gboolean a, gboolean b)
+{
+ if ((a && b) || (!a && !b))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+gboolean
+ve_is_string_in_list (const GList *list, const char *string)
+{
+ g_return_val_if_fail (string != NULL, FALSE);
+
+ while (list != NULL) {
+ if (list->data != NULL &&
+ strcmp (string, list->data) == 0)
+ return TRUE;
+
+ list = list->next;
+ }
+
+ return FALSE;
+}
+
+gboolean
+ve_is_string_in_list_case_no_locale (const GList *list, const char *string)
+{
+ g_return_val_if_fail (string != NULL, FALSE);
+
+ while (list != NULL) {
+ if (list->data != NULL &&
+ g_ascii_strcasecmp (string, list->data) == 0)
+ return TRUE;
+
+ list = list->next;
+ }
+
+ return FALSE;
+}
+
+char *
+ve_find_file_simple (const char *filename, const GList *directories)
+{
+ char *s;
+ const GList *li;
+
+ if (filename == NULL)
+ return NULL;
+
+ if (g_access (filename, F_OK) == 0)
+ return g_strdup (filename);
+
+ /* an absolute path is just checked */
+ if (g_path_is_absolute (filename))
+ return NULL;
+
+ for (li = directories; li != NULL; li = li->next) {
+ s = g_build_filename (li->data, filename, NULL);
+ if (g_access (s, F_OK) == 0)
+ return s;
+ g_free (s);
+ }
+
+ return NULL;
+}
+
+char *
+ve_locale_to_utf8 (const char *str)
+{
+ char *ret = g_locale_to_utf8 (str, -1, NULL, NULL, NULL);
+ if (ret == NULL) {
+ g_warning ("string not in proper locale encoding: \"%s\"", str);
+ return g_strdup (str);
+ } else {
+ return ret;
+ }
+}
+
+char *
+ve_locale_from_utf8 (const char *str)
+{
+ char *ret = g_locale_from_utf8 (str, -1, NULL, NULL, NULL);
+ if (ret == NULL) {
+ g_warning ("string not in proper utf8 encoding: \"%s\"", str);
+ return g_strdup (str);
+ } else {
+ return ret;
+ }
+}
+
+char *
+ve_filename_to_utf8 (const char *str)
+{
+ char *ret = g_filename_to_utf8 (str, -1, NULL, NULL, NULL);
+ if (ret == NULL) {
+ g_warning ("string not in proper locale encoding: \"%s\"", str);
+ return g_strdup (str);
+ } else {
+ return ret;
+ }
+}
+
+char *
+ve_filename_from_utf8 (const char *str)
+{
+ char *ret = g_filename_from_utf8 (str, -1, NULL, NULL, NULL);
+ if (ret == NULL) {
+ g_warning ("string not in proper utf8 encoding: \"%s\"", str);
+ return g_strdup (str);
+ } else {
+ return ret;
+ }
+}
+
+char *
+ve_strftime (struct tm *the_tm, const char *format)
+{
+ char str[1024];
+ char *loc_format = ve_locale_from_utf8 (format);
+
+ if (strftime (str, sizeof (str)-1, loc_format, the_tm) == 0) {
+ /* according to docs, if the string does not fit, the
+ * contents of str are undefined, thus just use
+ * ??? */
+ strcpy (str, "???");
+ }
+ str [sizeof (str)-1] = '\0'; /* just for sanity */
+ g_free (loc_format);
+
+ return ve_locale_to_utf8 (str);
+}
+
+pid_t
+ve_waitpid_no_signal (pid_t pid, int *status, int options)
+{
+ pid_t ret;
+
+ for (;;) {
+ ret = waitpid (pid, status, options);
+ if (ret == 0)
+ return 0;
+ if (errno != EINTR)
+ return ret;
+ }
+}
+
+gboolean
+ve_locale_exists (const char *loc)
+{
+ gboolean ret;
+ char *old = g_strdup (setlocale (LC_MESSAGES, NULL));
+ if (setlocale (LC_MESSAGES, loc) != NULL)
+ ret = TRUE;
+ else
+ ret = FALSE;
+ setlocale (LC_MESSAGES, old);
+ g_free (old);
+ return ret;
+}
+
+char *
+ve_find_prog_in_path (const char *prog, const char *path)
+{
+ char **vec;
+ int i;
+
+ if (ve_string_empty (prog) || ve_string_empty (path))
+ return NULL;
+
+ vec = g_strsplit (path, ":", -1);
+ for (i = 0; vec != NULL && vec[i] != NULL; i++) {
+ char *full = g_build_filename (vec[i], prog, NULL);
+ /* Do not use X_OK, we may be looking for things
+ that are not executables */
+ if (g_access (full, F_OK) == 0) {
+ g_strfreev(vec);
+ return full;
+ }
+ g_free (full);
+ }
+ g_strfreev(vec);
+ return NULL;
+}
+
+gboolean
+ve_is_prog_in_path (const char *prog, const char *path)
+{
+ char *full = ve_find_prog_in_path (prog, path);
+ if (full != NULL) {
+ g_free (full);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+char *
+ve_shell_quote_filename (const char *name)
+{
+ if (name[0] != '-') {
+ return g_shell_quote (name);
+ } else {
+ char *fname = g_strconcat ("./", name, NULL);
+ char *quoted = g_shell_quote (fname);
+ g_free (fname);
+ return quoted;
+ }
+}
diff --git a/common/gdm-common.h b/common/gdm-common.h
new file mode 100644
index 00000000..92dd8108
--- /dev/null
+++ b/common/gdm-common.h
@@ -0,0 +1,102 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * (c) 2000 Eazel, Inc.
+ * (c) 2001,2002 George Lebl
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GDM_COMMON_H
+#define _GDM_COMMON_H
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <locale.h>
+
+#include "ve-signal.h"
+#include "gdm-common-config.h"
+
+G_BEGIN_DECLS
+void ve_clearenv (void);
+char * ve_first_word (const char *s);
+gboolean ve_first_word_executable (const char *s,
+ gboolean only_existance);
+char * ve_rest (const char *s);
+
+/* Gets the first existing command out of a list separated by semicolons */
+char * ve_get_first_working_command (const char *list,
+ gboolean only_existance);
+
+gboolean ve_bool_equal (gboolean a, gboolean b);
+
+gboolean ve_is_string_in_list (const GList *list,
+ const char *string);
+gboolean ve_is_string_in_list_case_no_locale (const GList *list,
+ const char *string);
+
+#define ve_string_empty(x) ((x)==NULL||(x)[0]=='\0')
+#define ve_sure_string(x) ((x)!=NULL?(x):"")
+
+/* Find a file using the specified list of directories, an absolute path is
+ * just checked, whereas a relative path is search in the given directories,
+ */
+char * ve_find_file_simple (const char *filename,
+ const GList *directories);
+
+/* Find a file using the specified list of directories, an absolute path is
+ * just checked, whereas a relative path is search in the given directories,
+ * gnome_datadir, g_get_prgname() subdirectory, in GNOME_PATH
+ * under /share/ and /share/<g_get_prgname()> */
+char * ve_find_file (const char *filename,
+ const GList *directories);
+
+/* These two functions will ALWAYS return a non-NULL string,
+ * if there is an error, they return the unconverted string */
+char * ve_locale_to_utf8 (const char *str);
+char * ve_locale_from_utf8 (const char *str);
+
+/* These two functions will ALWAYS return a non-NULL string,
+ * if there is an error, they return the unconverted string */
+char * ve_filename_to_utf8 (const char *str);
+char * ve_filename_from_utf8 (const char *str);
+
+/* works with utf-8 strings and always returns something */
+char * ve_strftime (struct tm *the_tm, const char *format);
+
+/* function which doesn't stop on signals */
+pid_t ve_waitpid_no_signal (pid_t pid, int *status, int options);
+
+/* Testing for existance of a certain locale */
+gboolean ve_locale_exists (const char *loc);
+
+char * ve_find_prog_in_path (const char *prog, const char *path);
+gboolean ve_is_prog_in_path (const char *prog, const char *path);
+
+char *ve_shell_quote_filename (const char *name);
+
+#define VE_IGNORE_EINTR(expr) \
+ do { \
+ errno = 0; \
+ expr; \
+ } while G_UNLIKELY (errno == EINTR);
+
+G_END_DECLS
+
+#endif /* _GDM_COMMON_H */
diff --git a/common/ve-signal.c b/common/ve-signal.c
new file mode 100644
index 00000000..76f7ed4e
--- /dev/null
+++ b/common/ve-signal.c
@@ -0,0 +1,160 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Signal routines
+ *
+ * (c) 2000, 2002 Queen of England
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "config.h"
+
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include "ve-signal.h"
+
+typedef struct _SignalSource SignalSource;
+struct _SignalSource {
+ GSource source;
+
+ int signal;
+ guint8 index;
+ guint8 shift;
+};
+
+static guint32 signals_notified[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static gboolean
+ve_signal_prepare (GSource *source,
+ int *timeout)
+{
+ SignalSource *ss = (SignalSource *)source;
+
+ return signals_notified[ss->index] & (1 << ss->shift);
+}
+
+static gboolean
+ve_signal_check (GSource *source)
+{
+ SignalSource *ss = (SignalSource *)source;
+
+ return signals_notified[ss->index] & (1 << ss->shift);
+}
+
+static gboolean
+ve_signal_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ SignalSource *ss = (SignalSource *)source;
+
+ signals_notified[ss->index] &= ~(1 << ss->shift);
+
+ return ((VeSignalFunc)callback) (ss->signal, user_data);
+}
+
+static GSourceFuncs signal_funcs = {
+ ve_signal_prepare,
+ ve_signal_check,
+ ve_signal_dispatch
+};
+
+guint
+ve_signal_add (int signal,
+ VeSignalFunc function,
+ gpointer data)
+{
+ return ve_signal_add_full (G_PRIORITY_DEFAULT, signal, function, data, NULL);
+}
+
+guint
+ve_signal_add_full (int priority,
+ int signal,
+ VeSignalFunc function,
+ gpointer data,
+ GDestroyNotify destroy)
+{
+ GSource *source;
+ SignalSource *ss;
+ guint s = 128 + signal;
+
+ g_return_val_if_fail (function != NULL, 0);
+
+ source = g_source_new (&signal_funcs, sizeof (SignalSource));
+ ss = (SignalSource *)source;
+
+ ss->signal = signal;
+ ss->index = s / 32;
+ ss->shift = s % 32;
+
+ g_assert (ss->index < 8);
+
+ g_source_set_priority (source, priority);
+ g_source_set_callback (source, (GSourceFunc)function, data, destroy);
+ g_source_set_can_recurse (source, TRUE);
+
+ return g_source_attach (source, NULL);
+}
+
+void
+ve_signal_notify (int signal)
+{
+ guint index, shift;
+ guint s = 128 + signal;
+
+ index = s / 32;
+ shift = s % 32;
+
+ g_assert (index < 8);
+
+ signals_notified[index] |= 1 << shift;
+
+ g_main_context_wakeup (NULL);
+}
+
+gboolean
+ve_signal_was_notified (int signal)
+{
+ guint index, shift;
+ guint s = 128 + signal;
+
+ index = s / 32;
+ shift = s % 32;
+
+ g_assert (index < 8);
+
+ return ((signals_notified[index]) & (1 << shift)) ? TRUE : FALSE;
+}
+
+void
+ve_signal_unnotify (int signal)
+{
+ guint index, shift;
+ guint s = 128 + signal;
+
+ index = s / 32;
+ shift = s % 32;
+
+ g_assert (index < 8);
+
+ signals_notified[index] &= ~(1 << shift);
+}
diff --git a/common/ve-signal.h b/common/ve-signal.h
new file mode 100644
index 00000000..f8f4c4c3
--- /dev/null
+++ b/common/ve-signal.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Signal routines
+ *
+ * (c) 2000, 2002 Queen of England
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _VE_SIGNAL_H
+#define _VE_SIGNAL_H
+
+#include <glib.h>
+
+typedef gboolean (*VeSignalFunc) (int signal,
+ gpointer data);
+guint ve_signal_add (int signal,
+ VeSignalFunc function,
+ gpointer data);
+guint ve_signal_add_full (int priority,
+ int signal,
+ VeSignalFunc function,
+ gpointer data,
+ GDestroyNotify destroy);
+/* You must handle the signal notify yourself, you add
+ * this function as the signal notification function
+ * however */
+void ve_signal_notify (int signal);
+
+gboolean ve_signal_was_notified (int signal);
+void ve_signal_unnotify (int signal);
+
+#endif /* _VE_CONFIG_H */