#include "config.h"
#include <gnome.h>
#include <gconf/gconf-client.h>
#include <gdk/gdkx.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <libhal.h>
#include <signal.h>
#include "gvm.h"
#ifdef ENABLE_NLS
# include <libintl.h>
# define _(String) gettext (String)
# ifdef gettext_noop
# define N_(String) gettext_noop (String)
# else
# define N_(String) (String)
# endif
#else
# define _(String)
# define N_(String) (String)
#endif
#define GVM_DEBUG
#ifdef GVM_DEBUG
# define dbg(fmt,arg...) fprintf(stderr, "%s/%d: " fmt,__FILE__,__LINE__,##arg)
#else
# define dbg(fmt,arg...) do { } while(0)
#endif
#define warn(fmt,arg...) g_warning("%s/%d: " fmt,__FILE__,__LINE__,##arg)
#define NAUTILUS_COMMAND BIN_NAUTILUS" -n --no-desktop %m"
static struct gvm_configuration config;
static LibHalContext *hal_ctx;
static GSList *mounted_volumes_policy_queue = NULL;
static GSList *all_mounted_volumes = NULL;
static void
gvm_load_config (void)
{
config.automount_drives = gconf_client_get_bool (config.client,
GCONF_ROOT "automount_drives", NULL);
config.automount_media = gconf_client_get_bool (config.client,
GCONF_ROOT "automount_media", NULL);
config.autoplay_cda = gconf_client_get_bool (config.client,
GCONF_ROOT "autoplay_cda", NULL);
config.autobrowse = gconf_client_get_bool (config.client,
GCONF_ROOT "autobrowse", NULL);
config.autorun = gconf_client_get_bool(config.client,
GCONF_ROOT "autorun", NULL);
config.autophoto = gconf_client_get_bool(config.client,
GCONF_ROOT "autophoto", NULL);
config.autoplay_dvd = gconf_client_get_bool (config.client,
GCONF_ROOT "autoplay_dvd", NULL);
config.autoplay_cda_command = gconf_client_get_string (config.client,
GCONF_ROOT "autoplay_cda_command", NULL);
config.autorun_path = gconf_client_get_string (config.client,
GCONF_ROOT "autorun_path", NULL);
config.autoplay_dvd_command = gconf_client_get_string (config.client,
GCONF_ROOT "autoplay_dvd_command", NULL);
config.autoburn_cdr = gconf_client_get_bool (config.client,
GCONF_ROOT "autoburn_cdr", NULL);
config.autoburn_cdr_command = gconf_client_get_string (config.client,
GCONF_ROOT "autoburn_cdr_command", NULL);
config.autophoto_command = gconf_client_get_string (config.client,
GCONF_ROOT "autophoto_command", NULL);
config.eject_command = gconf_client_get_string (config.client,
GCONF_ROOT "eject_command", NULL);
if (!(config.automount_drives || config.autobrowse || config.autorun
|| config.autoplay_cda || config.autoplay_dvd
|| config.autophoto)) {
dbg ("daemon exit: no point living\n");
exit (EXIT_SUCCESS);
}
}
static void
gvm_config_changed (GConfClient *client __attribute__((__unused__)),
guint id __attribute__((__unused__)),
GConfEntry *entry __attribute__((__unused__)),
gpointer data __attribute__((__unused__)))
{
g_free (config.autoplay_cda_command);
g_free (config.autorun_path);
g_free (config.autoplay_dvd_command);
g_free (config.autoburn_cdr_command);
g_free (config.autophoto_command);
g_free (config.eject_command);
gvm_load_config ();
}
static void
gvm_init_config (void)
{
config.client = gconf_client_get_default ();
gconf_client_add_dir (config.client, GCONF_ROOT_SANS_SLASH,
GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
gvm_load_config ();
gconf_client_notify_add (config.client, GCONF_ROOT_SANS_SLASH,
gvm_config_changed, NULL, NULL, NULL);
}
static void
gvm_run_command (const char *device, const char *command,
const char *path, const char *udi)
{
char *argv[4];
gchar *new_command;
GError *error = NULL;
GString *exec = g_string_new (NULL);
char *p, *q;
new_command = g_strdup (command);
q = new_command;
p = new_command;
while ((p = strchr (p, '%')) != NULL) {
if (*(p + 1) == 'd') {
if (device == NULL)
goto error;
*p = '\0';
g_string_append (exec, q);
g_string_append (exec, device);
q = p + 2;
p = p + 2;
} else if (*(p + 1) == 'm') {
if (path == NULL)
goto error;
*p = '\0';
g_string_append (exec, q);
g_string_append (exec, path);
q = p + 2;
p = p + 2;
} else if (*(p + 1) == 'h') {
if (udi == NULL)
goto error;
*p = '\0';
g_string_append (exec, q);
g_string_append (exec, "\"");
g_string_append (exec, udi);
g_string_append (exec, "\"");
q = p + 2;
p = p + 2;
}
}
g_string_append (exec, q);
argv[0] = "/bin/sh";
argv[1] = "-c";
argv[2] = exec->str;
argv[3] = NULL;
g_spawn_async (g_get_home_dir (), argv, NULL, 0, NULL, NULL,
NULL, &error);
if (error)
warn ("failed to exec %s: %s\n", exec->str, error->message);
g_string_free (exec, TRUE);
g_free (new_command);
return;
error:
warn ("command '%s' required unavailable parameter; "
"%%d='%s' %%m='%s' %%h='%s'\n", command, device, path, udi);
g_string_free (exec, TRUE);
g_free (new_command);
}
static gboolean
gvm_ask_autorun (const char *path)
{
GtkWidget *askme;
gboolean retval;
askme = gtk_message_dialog_new (NULL,
0, GTK_MESSAGE_WARNING,
GTK_BUTTONS_NONE,
_("Run command from inserted media?"));
gtk_message_dialog_format_secondary_text (GTK_DIALOG (askme),
_("The file \"%s\" on the inserted media is an auto-run"
"file."));
gtk_dialog_add_buttons (GTK_DIALOG (askme),
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
_("_Run Command"), GTK_RESPONSE_ACCEPT,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (askme), GTK_RESPONSE_ACCEPT);
switch (gtk_dialog_run (GTK_DIALOG (askme))) {
case GTK_RESPONSE_ACCEPT:
retval = TRUE;
break;
case GTK_RESPONSE_REJECT:
default:
retval = FALSE;
break;
}
gtk_widget_destroy (askme);
return retval;
}
static gboolean
gvm_check_dvd (const char *device, const char *mount_point, const char *udi)
{
char *path;
gboolean retval;
path = g_build_path (G_DIR_SEPARATOR_S, mount_point, "video_ts", NULL);
retval = g_file_test (path, G_FILE_TEST_IS_DIR);
g_free (path);
if (retval == FALSE) {
path = g_build_path (G_DIR_SEPARATOR_S, mount_point,
"VIDEO_TS", NULL);
retval = g_file_test (path, G_FILE_TEST_IS_DIR);
g_free (path);
}
if (retval && config.autoplay_dvd)
gvm_run_command (device, config.autoplay_dvd_command,
mount_point, udi);
return retval;
}
static gboolean
gvm_check_photos (const char *udi, const char *device, const char *mount_point)
{
char *dcim_path;
enum { IMPORT } action = -1;
GtkWidget *askme;
int retval = FALSE;
dcim_path = g_build_path (G_DIR_SEPARATOR_S, mount_point, "dcim", NULL);
if (!g_file_test (dcim_path, G_FILE_TEST_IS_DIR))
goto out;
retval = TRUE;
dbg ("Photos detected: %s\n", dcim_path);
if (!hal_device_add_capability (hal_ctx, udi, "content.photos"))
warn ("failed to set content.photos on %s\n", device);
if (config.autophoto) {
askme = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_WARNING,
GTK_BUTTONS_NONE,
_("Import photos from device?"));
gtk_message_dialog_format_secondary_text (GTK_DIALOG (askme),
_("There are photos on the inserted media. "
"Would you like to import these "
"photos into your photo album?"));
gtk_dialog_add_buttons (GTK_DIALOG (askme),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
_("_Import Photos"), IMPORT,
NULL);
action = gtk_dialog_run (GTK_DIALOG (askme));
gtk_widget_destroy (askme);
if (action == IMPORT)
gvm_run_command (device, config.autophoto_command,
dcim_path, udi);
}
out:
g_free (dcim_path);
return retval;
}
static gboolean
gvm_check_camera (const char *udi)
{
enum { IMPORT } action = -1;
GtkWidget *askme;
int retval = FALSE;
if (!hal_device_query_capability(hal_ctx, udi, "camera"))
goto out;
retval = TRUE;
dbg ("Camera detected: %s\n", udi);
if (config.autophoto) {
askme = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_WARNING,
GTK_BUTTONS_NONE,
_("Import photos from camera?"));
gtk_message_dialog_format_secondary_text (GTK_DIALOG (askme),
_("There are photos on the plugged-in camera. "
"Would you like to import these "
"photos into your photo album?"));
gtk_dialog_add_buttons (GTK_DIALOG (askme),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
_("_Import Photos"), IMPORT,
NULL);
action = gtk_dialog_run (GTK_DIALOG (askme));
gtk_widget_destroy (askme);
if (action == IMPORT)
gvm_run_command (NULL, config.autophoto_command,
NULL, udi);
}
out:
return retval;
}
static void
gvm_device_autorun (const char *udi)
{
char *device = NULL, *mount_point = NULL;
gboolean autorun_succeeded = FALSE;
device = hal_device_get_property_string (hal_ctx, udi, "block.device");
if (!device) {
warn ("cannot get block.device\n");
goto out;
}
mount_point = hal_device_get_property_string (hal_ctx, udi,
"volume.mount_point");
if (!mount_point) {
warn ("cannot get volume.mount_point\n");
goto out;
}
if (gvm_check_dvd (device, mount_point, udi))
goto out;
if (gvm_check_photos (udi, device, mount_point))
goto out;
if (config.autorun == TRUE && config.autorun_path) {
char **autorun_fns;
int i;
autorun_fns = g_strsplit (config.autorun_path, ":", -1);
for (i = 0; autorun_fns[i]; i++) {
char *path, *argv[2];
path = g_strdup_printf ("%s/%s", mount_point,
autorun_fns[i]);
argv[0] = path;
argv[1] = NULL;
if (access (path, X_OK))
continue;
if (gvm_ask_autorun (path)) {
GError *error = NULL;
g_spawn_async (g_get_home_dir (), argv, NULL,
0, NULL, NULL, NULL, &error);
if (error)
warn ("failed to exec %s: %s\n", path,
error->message);
else
autorun_succeeded = TRUE;
g_free (path);
break;
}
g_free (path);
}
g_strfreev (autorun_fns);
}
if ((config.autobrowse == TRUE) && (autorun_succeeded == FALSE)) {
gvm_run_command (device, NAUTILUS_COMMAND, mount_point, udi);
}
out:
hal_free_string (device);
hal_free_string (mount_point);
}
static gboolean
gvm_device_mount (char *device)
{
char *argv[3];
GError *error = NULL;
gint exit_status;
argv[0] = BIN_MOUNT;
argv[1] = device;
argv[2] = NULL;
if (!g_spawn_sync (g_get_home_dir (), argv, NULL, 0, NULL,
NULL, NULL, NULL, &exit_status, &error)) {
warn ("failed to exec " BIN_MOUNT ": %s\n", error->message);
return FALSE;
}
return (exit_status == 0);
}
static gboolean
gvm_device_unmount (char *device)
{
char *argv[3];
GError *error = NULL;
gint exit_status;
argv[0] = BIN_UMOUNT;
argv[1] = device;
argv[2] = NULL;
if (!g_spawn_sync (g_get_home_dir (), argv, NULL, 0, NULL,
NULL, NULL, NULL, &exit_status, &error)) {
warn ("failed to exec " BIN_MOUNT ": %s\n", error->message);
return FALSE;
}
return (exit_status == 0);
}
static void
gvm_run_cdplayer (const char *device, const char *mount_point, const char *udi)
{
if (config.autoplay_cda)
gvm_run_command (device, config.autoplay_cda_command,
mount_point, udi);
}
static void
gvm_ask_mixed (const char *udi)
{
enum { MOUNT, PLAY } action = -1;
char *device = NULL, *mount_point = NULL;
device = hal_device_get_property_string (hal_ctx, udi, "block.device");
if (!device) {
warn ("cannot get block.device\n");
goto out;
}
if (config.automount_media && config.autoplay_cda) {
GtkWidget *askme;
askme = gtk_message_dialog_new (NULL, 0,
GTK_MESSAGE_WARNING,
GTK_BUTTONS_NONE,
_("Browse files or play tracks from disc?"));
gtk_message_dialog_format_secondary_text (GTK_DIALOG (askme),
_("There are both audio tracks and "
"data files on the inserted disc. "
"Choose if you want to play the audio "
"tracks to listen to music or browse "
"the files to manage the stored data."));
gtk_dialog_add_buttons (GTK_DIALOG (askme),
_("_Browse Files"), MOUNT,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
_("_Play Tracks"), PLAY,
NULL);
action = gtk_dialog_run (GTK_DIALOG (askme));
gtk_widget_destroy (askme);
} else if (config.automount_media)
action = MOUNT;
else if (config.autoplay_cda)
action = PLAY;
switch (action) {
case MOUNT:
gvm_device_mount (device);
mounted_volumes_policy_queue = g_slist_append (mounted_volumes_policy_queue, g_strdup (udi));
break;
case PLAY:
gvm_run_cdplayer (device, device, udi);
break;
default:
break;
}
out:
hal_free_string (device);
hal_free_string (mount_point);
}
static void
gvm_run_cdburner (const char *device, const char *mount, const char *udi)
{
if (config.autoburn_cdr)
gvm_run_command (device, config.autoburn_cdr_command, mount, udi);
}
static gboolean
gvm_device_is_writer (const char *udi)
{
if ((hal_device_get_property_bool (hal_ctx, udi, "storage.cdrom.cdr")) ||
(hal_device_get_property_bool (hal_ctx, udi, "storage.cdrom.cdrw")) ||
(hal_device_get_property_bool (hal_ctx, udi, "storage.cdrom.dvdr")) ||
(hal_device_get_property_bool (hal_ctx, udi, "storage.cdrom.dvdram")) ||
(hal_device_get_property_bool (hal_ctx, udi, "storage.cdrom.dvdplusr")) ||
(hal_device_get_property_bool (hal_ctx, udi, "storage.cdrom.dvdplusrw")))
return TRUE;
return FALSE;
}
static void
gvm_cdrom_policy (const char *udi)
{
char *device = NULL;
char *drive_udi = NULL;
dbus_bool_t has_audio;
dbus_bool_t has_data;
dbus_bool_t is_blank;
has_audio = hal_device_get_property_bool (hal_ctx, udi,
"volume.disc.has_audio");
has_data = hal_device_get_property_bool (hal_ctx, udi,
"volume.disc.has_data");
is_blank = hal_device_get_property_bool (hal_ctx, udi,
"volume.disc.is_blank");
drive_udi = hal_device_get_property_string(hal_ctx, udi,
"info.parent");
device = hal_device_get_property_string (hal_ctx, udi, "block.device");
if (!device) {
warn ("cannot get block.device\n");
goto out;
}
if (has_audio && (!has_data)) {
gvm_run_cdplayer (device, device, udi);
} else if (has_audio && has_data) {
gvm_ask_mixed (udi);
} else if (has_data) {
if (config.automount_media) {
gvm_device_mount (device);
mounted_volumes_policy_queue = g_slist_append (mounted_volumes_policy_queue, g_strdup (udi));
}
} else if (is_blank) {
if (gvm_device_is_writer (drive_udi))
gvm_run_cdburner (device, device, udi);
}
out:
hal_free_string (device);
hal_free_string (drive_udi);
}
static void
gvm_media_changed (const char *udi, const char *storage_device,
const char *device)
{
char *media_type;
if (hal_device_property_exists (
hal_ctx, storage_device, "info.locked") &&
hal_device_get_property_bool (
hal_ctx, storage_device, "info.locked")) {
dbg ("Drive with udi %s is locked through hal; "
"skipping policy\n", storage_device);
return;
}
media_type = hal_device_get_property_string (hal_ctx, storage_device,
"storage.drive_type");
if (!media_type) {
warn ("cannot get storage.drive_type\n");
return;
}
if (!g_strcasecmp (media_type, "cdrom")) {
gvm_cdrom_policy (udi);
} else {
dbg ("Added: %s\n", device);
if (config.automount_drives) {
gvm_device_mount (device);
mounted_volumes_policy_queue = g_slist_append (mounted_volumes_policy_queue, g_strdup (udi));
}
}
hal_free_string (media_type);
}
static void
hal_device_added (LibHalContext *ctx __attribute__((__unused__)),
const char *udi)
{
char *device = NULL, *storage_device = NULL;
dbg ("New Device: %s\n", udi);
gvm_check_camera (udi);
if (!hal_device_query_capability(hal_ctx, udi, "block"))
goto out;
if (!hal_device_get_property_bool (hal_ctx, udi,
"block.is_volume"))
goto out;
device = hal_device_get_property_string (hal_ctx, udi,
"block.device");
if (!device) {
dbg ("cannot get block.device\n");
goto out;
}
storage_device = hal_device_get_property_string (
hal_ctx, udi,
"block.storage_device");
if (!storage_device) {
dbg ("cannot get block.storage_device\n");
goto out;
}
if (hal_device_get_property_bool (hal_ctx, storage_device,
"storage.removable")) {
dbg ("Changed: %s\n", device);
gvm_media_changed (udi, storage_device, device);
goto out;
}
dbg ("Added: %s\n", device);
if (config.automount_drives) {
gvm_device_mount (device);
mounted_volumes_policy_queue = g_slist_append (mounted_volumes_policy_queue, g_strdup (udi));
}
out:
hal_free_string (device);
hal_free_string (storage_device);
}
static void
hal_device_removed (LibHalContext *ctx __attribute__((__unused__)),
const char *udi)
{
dbg ("Device removed: %s\n", udi);
}
static void
hal_device_new_capability (LibHalContext *ctx __attribute__((__unused__)),
const char *udi __attribute__((__unused__)),
const char *capability __attribute__((__unused__)))
{
}
static void
hal_device_lost_capability (LibHalContext *ctx __attribute__((__unused__)),
const char *udi __attribute__((__unused__)),
const char *capability __attribute__((__unused__)))
{
}
static void
hal_property_modified (LibHalContext *ctx __attribute__((__unused__)),
const char *udi,
const char *key,
dbus_bool_t is_removed __attribute__((__unused__)),
dbus_bool_t is_added __attribute__((__unused__)))
{
dbus_bool_t val;
GSList *i;
GSList *next;
if (g_strcasecmp (key, "volume.is_mounted") != 0)
return;
val = hal_device_get_property_bool (hal_ctx, udi, key);
if (val == TRUE) {
GSList *policy_udi;
dbg ("Mounted: %s\n", udi);
all_mounted_volumes = g_slist_append (all_mounted_volumes,
g_strdup (udi));
policy_udi = g_slist_find_custom (mounted_volumes_policy_queue,
udi,
g_ascii_strcasecmp);
if (policy_udi != NULL) {
g_free (policy_udi->data);
mounted_volumes_policy_queue = g_slist_delete_link (mounted_volumes_policy_queue,
policy_udi);
gvm_device_autorun (udi);
}
} else {
dbg ("Unmounted: %s\n", udi);
for (i=all_mounted_volumes; i != NULL; i = next) {
next = g_slist_next (i);
if (strcmp (udi, (const char *)i->data) == 0) {
g_free (i->data);
all_mounted_volumes =
g_slist_delete_link (
all_mounted_volumes, i);
break;
}
}
}
}
static void
hal_device_condition (LibHalContext *ctx __attribute__((__unused__)),
const char *udi __attribute__((__unused__)),
const char *condition_name __attribute__((__unused__)),
DBusMessage * message __attribute__((__unused__)))
{
}
static void
hal_mainloop_integration (LibHalContext *ctx __attribute__((__unused__)),
DBusConnection * dbus_connection)
{
dbus_connection_setup_with_g_main (dbus_connection, NULL);
}
static LibHalContext *
gvm_do_hal_init (LibHalFunctions *functions)
{
LibHalContext *ctx;
char **devices;
int nr;
ctx = hal_initialize (functions, FALSE);
if (!ctx) {
warn ("failed to initialize HAL!\n");
return NULL;
}
if (hal_device_property_watch_all (ctx)) {
warn ("failed to watch all HAL properties!\n");
hal_shutdown (ctx);
return NULL;
}
devices = hal_get_all_devices (ctx, &nr);
if (!devices) {
warn ("seems that HAL is not running\n");
hal_shutdown (ctx);
return NULL;
}
hal_free_string_array (devices);
return ctx;
}
static void mount_all (LibHalContext *ctx)
{
int i;
int num_volumes;
char **volumes;
char *udi;
char *device_file;
if (!config.automount_media)
return;
volumes = hal_find_device_by_capability (ctx, "volume", &num_volumes);
for (i = 0; i < num_volumes; i++) {
udi = volumes [i];
if (!hal_device_property_exists (ctx, udi,
"volume.is_mounted") ||
hal_device_get_property_bool (ctx, udi,
"volume.is_mounted"))
continue;
if (!hal_device_property_exists (ctx, udi,
"volume.fsusage") ||
strcmp (hal_device_get_property_string (ctx, udi,
"volume.fsusage"),
"filesystem") != 0)
continue;
device_file = hal_device_get_property_string (ctx, udi,
"block.device");
if (device_file != NULL ) {
dbg ("mount_all: mounting %s\n", device_file);
gvm_device_mount (device_file);
hal_free_string (device_file);
} else
warn ("no device_file for udi=%s\n", udi);
}
hal_free_string_array (volumes);
}
static void
unmount_all (LibHalContext *ctx)
{
GSList *i;
char *device_file;
char *udi;
dbg ("unmounting all volumes that we saw mounted in our life\n");
for (i = all_mounted_volumes; i != NULL; i = g_slist_next (i)) {
udi = i->data;
device_file = hal_device_get_property_string (ctx, udi,
"block.device");
if (device_file != NULL ) {
dbg ("unmount_all: unmounting %s\n", device_file);
gvm_device_unmount (device_file);
hal_free_string (device_file);
} else {
warn ("no device_file for udi=%s\n", udi);
}
}
}
static int sigterm_unix_signal_pipe_fds[2];
static GIOChannel *sigterm_iochn;
static void
handle_sigterm (int value)
{
static char marker[1] = {'S'};
write (sigterm_unix_signal_pipe_fds[1], marker, 1);
}
static gboolean
sigterm_iochn_data (GIOChannel *source,
GIOCondition condition,
gpointer user_data)
{
GError *err = NULL;
gchar data[1];
gsize bytes_read;
if (G_IO_STATUS_NORMAL !=
g_io_channel_read_chars (source, data, 1, &bytes_read, &err)) {
warn ("Error emptying callout notify pipe: %s",
err->message);
g_error_free (err);
goto out;
}
dbg ("Received SIGTERM, initiating shutdown\n");
unmount_all (hal_ctx);
gtk_main_quit();
out:
return TRUE;
}
static void
gvm_die (GnomeClient *client, gpointer user_data)
{
dbg ("Received 'die', initiating shutdown\n");
unmount_all (hal_ctx);
gtk_main_quit ();
}
int
main (int argc, char *argv[])
{
GnomeClient *client;
LibHalFunctions hal_functions = { hal_mainloop_integration,
hal_device_added,
hal_device_removed,
hal_device_new_capability,
hal_device_lost_capability,
hal_property_modified,
hal_device_condition };
gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE,
argc, argv, GNOME_PARAM_NONE);
bindtextdomain(PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset(PACKAGE, "UTF-8");
textdomain(PACKAGE);
client = gnome_master_client ();
if (gvm_get_clipboard ())
gnome_client_set_restart_style (client, GNOME_RESTART_ANYWAY);
else {
gnome_client_set_restart_style (client, GNOME_RESTART_NEVER);
warn ("already running?\n");
return 1;
}
gtk_signal_connect (GTK_OBJECT (client), "die",
GTK_SIGNAL_FUNC (gvm_die), NULL);
hal_ctx = gvm_do_hal_init (&hal_functions);
if (!hal_ctx)
return 1;
gvm_init_config ();
if (pipe (sigterm_unix_signal_pipe_fds) != 0) {
warn ("Could not setup pipe, errno=%d", errno);
return 1;
}
sigterm_iochn = g_io_channel_unix_new (sigterm_unix_signal_pipe_fds[0]);
if (sigterm_iochn == NULL) {
warn ("Could not create GIOChannel");
return 1;
}
g_io_add_watch (sigterm_iochn, G_IO_IN, sigterm_iochn_data, NULL);
signal (SIGTERM, handle_sigterm);
mount_all (hal_ctx);
gtk_main ();
return 0;
}