gvfs/daemon/main.c

243 lines
6.6 KiB
C
Raw Normal View History

2022-06-29 16:07:13 +08:00
/* GIO - GLib Input, Output and Streaming Library
*
* Copyright (C) 2006-2007 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
*/
#include <config.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include "gvfsdaemon.h"
#include "gvfsbackendtest.h"
#include <gvfsdaemonprotocol.h>
#include <gvfsutils.h>
#include "mount.h"
#include <locale.h>
static GMainLoop *loop;
static gboolean already_acquired = FALSE;
static int process_result = 0;
static void
on_name_lost (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
if (connection == NULL)
{
g_printerr ("A connection to the bus can't be made\n");
process_result = 1;
}
else
{
if (already_acquired)
{
g_printerr ("Got NameLost, some other instance replaced us\n");
}
else
{
g_printerr ("Failed to acquire daemon name, perhaps the VFS daemon is already running?\n");
process_result = 1;
}
}
g_main_loop_quit (loop);
}
static void
on_name_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
already_acquired = TRUE;
#ifdef HAVE_FUSE
gboolean no_fuse = GPOINTER_TO_UINT (user_data);
if (!no_fuse)
{
char *fuse_path;
char *argv2[6];
/* Use the old .gvfs location as fallback, not .cache/gvfs */
if (g_get_user_runtime_dir() == g_get_user_cache_dir ())
fuse_path = g_build_filename (g_get_home_dir(), ".gvfs", NULL);
else
fuse_path = g_build_filename (g_get_user_runtime_dir (), "gvfs", NULL);
if (!g_file_test (fuse_path, G_FILE_TEST_EXISTS))
g_mkdir (fuse_path, 0700);
/* The -f (foreground) option prevent libfuse to call daemon(). */
/* First, this is not required as g_spawn_async() already */
/* detach the process. Secondly, calling daemon() and then */
/* pthread_create() produce an undefined result accoring to */
/* Opengroup. On system with the uClibc library this will badly */
/* hang the process. */
argv2[0] = LIBEXEC_DIR "/gvfsd-fuse";
argv2[1] = fuse_path;
argv2[2] = "-f";
argv2[3] = NULL;
g_spawn_async (NULL,
argv2,
NULL,
G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
NULL, NULL,
NULL, NULL);
g_free (fuse_path);
}
#endif
}
static void
on_bus_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
if (!mount_init ())
{
/* we were not able to properly initialize ourselves, bail out */
g_main_loop_quit (loop);
return;
}
}
static void
daemon_shutdown (GVfsDaemon *daemon,
GMainLoop *loop)
{
if (g_main_loop_is_running (loop))
g_main_loop_quit (loop);
}
int
main (int argc, char *argv[])
{
GVfsDaemon *daemon;
gboolean replace;
gboolean no_fuse;
gboolean debugging;
gboolean show_version;
GError *error;
guint name_owner_id;
GBusNameOwnerFlags flags;
GOptionContext *context;
const GOptionEntry options[] = {
{ "replace", 'r', 0, G_OPTION_ARG_NONE, &replace, N_("Replace old daemon."), NULL },
{ "no-fuse", 0, 0, G_OPTION_ARG_NONE, &no_fuse, N_("Dont start fuse."), NULL },
{ "debug", 'd', 0, G_OPTION_ARG_NONE, &debugging, N_("Enable debug output."), NULL },
{ "version", 0, 0, G_OPTION_ARG_NONE, &show_version, N_("Show program version."), NULL},
{ NULL }
};
setlocale (LC_ALL, "");
bindtextdomain (GETTEXT_PACKAGE, GVFS_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
gvfs_setup_debug_handler ();
#ifdef SIGPIPE
signal (SIGPIPE, SIG_IGN);
#endif
g_set_application_name (_("GVFS Daemon"));
context = g_option_context_new ("");
g_option_context_set_summary (context, _("Main daemon for GVFS"));
g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
replace = FALSE;
no_fuse = FALSE;
debugging = FALSE;
show_version = FALSE;
if (g_getenv ("GVFS_DISABLE_FUSE") != NULL)
no_fuse = TRUE;
error = NULL;
if (!g_option_context_parse (context, &argc, &argv, &error))
{
/* Translators: the first %s is the application name, */
/* the second %s is the error message */
g_printerr (_("%s: %s"), g_get_application_name(), error->message);
g_printerr ("\n");
g_printerr (_("Try “%s --help” for more information."),
g_get_prgname ());
g_printerr ("\n");
g_error_free (error);
g_option_context_free (context);
return 1;
}
g_option_context_free (context);
if (g_getenv ("GVFS_DEBUG"))
debugging = TRUE;
gvfs_set_debug (debugging);
if (show_version)
{
g_print (PACKAGE_STRING "\n");
return 0;
}
loop = g_main_loop_new (NULL, FALSE);
daemon = g_vfs_daemon_new (TRUE, replace);
if (daemon == NULL)
return 1;
g_signal_connect (daemon, "shutdown",
G_CALLBACK (daemon_shutdown), loop);
flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
if (replace)
flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;
name_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
G_VFS_DBUS_DAEMON_NAME,
flags,
on_bus_acquired,
on_name_acquired,
on_name_lost,
GUINT_TO_POINTER (no_fuse),
NULL);
g_main_loop_run (loop);
mount_finalize ();
g_clear_object (&daemon);
if (name_owner_id != 0)
g_bus_unown_name (name_owner_id);
if (loop != NULL)
g_main_loop_unref (loop);
return process_result;
}