Exemple #1
0
/**
 * udisks_daemon_util_inhibit_system_sync:
 * @reason: A human readable explanation of why the system is being inhibited.
 *
 * Tries to inhibit the system.
 *
 * Right now only
 * <ulink url="http://www.freedesktop.org/wiki/Software/systemd/inhibit">systemd</ulink>
 * inhibitors are supported but other inhibitors can be added in the future.
 *
 * Returns: A cookie that can be used with udisks_daemon_util_uninhibit_system_sync().
 */
UDisksInhibitCookie *
udisks_daemon_util_inhibit_system_sync (const gchar  *reason)
{
#ifdef HAVE_LIBSYSTEMD_LOGIN
  UDisksInhibitCookie *ret = NULL;
  GDBusConnection *connection = NULL;
  GVariant *value = NULL;
  GUnixFDList *fd_list = NULL;
  gint32 index = -1;
  GError *error = NULL;

  g_return_val_if_fail (reason != NULL, NULL);

  connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
  if (connection == NULL)
    {
      udisks_error ("Error getting system bus: %s (%s, %d)",
                    error->message, g_quark_to_string (error->domain), error->code);
      g_clear_error (&error);
      goto out;
    }

  value = g_dbus_connection_call_with_unix_fd_list_sync (connection,
                                                         "org.freedesktop.login1",
                                                         "/org/freedesktop/login1",
                                                         "org.freedesktop.login1.Manager",
                                                         "Inhibit",
                                                         g_variant_new ("(ssss)",
                                                                        "sleep:shutdown:idle", /* what */
                                                                        "Disk Manager",        /* who */
                                                                        reason,                /* why */
                                                                        "block"),              /* mode */
                                                         G_VARIANT_TYPE ("(h)"),
                                                         G_DBUS_CALL_FLAGS_NONE,
                                                         -1,       /* default timeout */
                                                         NULL,     /* fd_list */
                                                         &fd_list, /* out_fd_list */
                                                         NULL, /* GCancellable */
                                                         &error);
  if (value == NULL)
    {
      udisks_error ("Error inhibiting: %s (%s, %d)",
                    error->message, g_quark_to_string (error->domain), error->code);
      g_clear_error (&error);
      goto out;
    }

  g_variant_get (value, "(h)", &index);
  g_assert (index >= 0 && index < g_unix_fd_list_get_length (fd_list));

  ret = g_new0 (UDisksInhibitCookie, 1);
  ret->magic = 0xdeadbeef;
  ret->fd = g_unix_fd_list_get (fd_list, index, &error);
  if (ret->fd == -1)
    {
      udisks_error ("Error getting fd: %s (%s, %d)",
                    error->message, g_quark_to_string (error->domain), error->code);
      g_clear_error (&error);
      g_free (ret);
      ret = NULL;
      goto out;
    }

 out:
  if (value != NULL)
    g_variant_unref (value);
  g_clear_object (&fd_list);
  g_clear_object (&connection);
  return ret;
#else
  /* non-systemd: just return a dummy pointer */
  g_return_val_if_fail (reason != NULL, NULL);
  return (UDisksInhibitCookie* ) &udisks_daemon_util_inhibit_system_sync;
#endif
}
Exemple #2
0
static void
invocation_client_create (GDBusConnection *connection,
                          const gchar *bus_name)
{
  InvocationClient *client;

  g_mutex_lock (&inv.mutex);
  client = g_hash_table_lookup (inv.clients, bus_name);
  g_mutex_unlock (&inv.mutex);

  if (client != NULL)
    return;

  /*
   * Each time we see an incoming function call, keep the service alive for
   * that client, and each invocation of the client
   *
   * We would also like to get client credentials here and not pass client
   * messages into the rest of the machinery until that has completed.
   * Unfortunately the necessary patch in gio has not yet been merged.
   *
   * So we do an async call and if it hasn't completed by the time we need
   * the caller credentials, then we block and wait for it. Since it's the
   * system bus responding, it should respond pretty quickly.
   *
   * See invocation_client_lookup() for the waiting side of things.
   */

  client = g_new0 (InvocationClient, 1);
  client->bus_name = g_strdup (bus_name);
  client->subject = polkit_system_bus_name_new (bus_name);
  client->refs = 1;
  client->uid_peer = ~0;
  client->uid_state = UID_LOADING;

  client->watch = g_bus_watch_name_on_connection (connection, bus_name,
                                                  G_BUS_NAME_WATCHER_FLAGS_NONE,
                                                  NULL, on_client_vanished, NULL, NULL);

  g_debug ("GetConnectionUnixUser('%s') ...", bus_name);

  /*
   * This async call in the GDBusWorker thread main context will not
   * be blocked by the daemon main context blocking.
   */

  g_dbus_connection_call (connection,
                          "org.freedesktop.DBus",  /* bus name */
                          "/org/freedesktop/DBus", /* object path */
                          "org.freedesktop.DBus",  /* interface */
                          "GetConnectionUnixUser", /* method */
                          g_variant_new ("(s)", bus_name),
                          G_VARIANT_TYPE ("(u)"),
                          G_DBUS_CALL_FLAGS_NONE,
                          -1, /* timeout_msec */
                          NULL, on_get_connection_unix_user,
                          g_strdup (bus_name));

  g_mutex_lock (&inv.mutex);
  if (!g_hash_table_lookup (inv.clients, bus_name))
    {
      g_hash_table_replace (inv.clients, client->bus_name, client);
      client = NULL;
    }
  g_mutex_unlock (&inv.mutex);

  if (client)
    {
      invocation_client_unref (client);
    }
  else
    {
      g_main_context_invoke_full (NULL, G_PRIORITY_DEFAULT,
                                  on_invoke_client_appeared,
                                  g_strdup (bus_name), g_free);
    }
}
Exemple #3
0
static void
method_call_cb (GDBusConnection *connection,
                const char *sender,
                const char *object_path,
                const char *interface_name,
                const char *method_name,
                GVariant *parameters,
                GDBusMethodInvocation *invocation,
                gpointer user_data)
{
	if (g_strcmp0 (method_name, "HandleArguments") == 0)
	{
		TerminalOptions *options = NULL;
		GVariant *v_wd, *v_display, *v_sid, *v_envv, *v_argv;
		char *working_directory = NULL, *display_name = NULL, *startup_id = NULL;
        int initial_workspace = -1;
		char **envv = NULL, **argv = NULL;
		int argc;
		GError *error = NULL;

        g_variant_get (parameters, "(@ay@ay@ay@ayi@ay)",
                       &v_wd, &v_display, &v_sid, &v_envv, &initial_workspace, &v_argv);

		working_directory = ay_to_string (v_wd, &error);
		if (error)
			goto out;
		display_name = ay_to_string (v_display, &error);
		if (error)
			goto out;
		startup_id = ay_to_string (v_sid, &error);
		if (error)
			goto out;
		envv = ay_to_strv (v_envv, NULL);
		argv = ay_to_strv (v_argv, &argc);

		_terminal_debug_print (TERMINAL_DEBUG_FACTORY,
                               "Factory invoked with working-dir='%s' display='%s' startup-id='%s'"
                               "workspace='%d'\n",
		                       working_directory ? working_directory : "(null)",
		                       display_name ? display_name : "(null)",
		                       startup_id ? startup_id : "(null)",
                               initial_workspace);

		options = terminal_options_parse (working_directory,
		                                  display_name,
		                                  startup_id,
		                                  envv,
		                                  TRUE,
		                                  TRUE,
		                                  &argc, &argv,
		                                  &error,
		                                  NULL);

        options->initial_workspace = initial_workspace;

		if (options != NULL)
		{
			terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error);
			terminal_options_free (options);
		}

out:
		g_variant_unref (v_wd);
		g_free (working_directory);
		g_variant_unref (v_display);
		g_free (display_name);
		g_variant_unref (v_sid);
		g_free (startup_id);
		g_variant_unref (v_envv);
		g_strfreev (envv);
		g_variant_unref (v_argv);
		g_strfreev (argv);

		if (error == NULL)
		{
			g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
		}
		else
		{
			g_dbus_method_invocation_return_gerror (invocation, error);
			g_error_free (error);
		}
	}
}
Exemple #4
0
static void
portal_add (GDBusMethodInvocation *invocation,
            GVariant *parameters,
            const char *app_id)
{
  GDBusMessage *message;
  GUnixFDList *fd_list;
  g_autofree char *id = NULL;
  g_autofree char *proc_path = NULL;
  int fd_id, fd, fds_len, fd_flags;
  glnx_fd_close int dir_fd = -1;
  const int *fds;
  char path_buffer[PATH_MAX+1];
  ssize_t symlink_size;
  struct stat st_buf, real_st_buf, real_parent_st_buf;
  g_autofree char *dirname = NULL;
  g_autofree char *name = NULL;
  gboolean reuse_existing, persistent;

  g_variant_get (parameters, "(hbb)", &fd_id, &reuse_existing, &persistent);

  message = g_dbus_method_invocation_get_message (invocation);
  fd_list = g_dbus_message_get_unix_fd_list (message);

  fd = -1;
  if (fd_list != NULL)
    {
      fds = g_unix_fd_list_peek_fds (fd_list, &fds_len);
      if (fd_id < fds_len)
        fd = fds[fd_id];
    }

  proc_path = g_strdup_printf ("/proc/self/fd/%d", fd);

  if (fd == -1 ||
      /* Must be able to get fd flags */
      (fd_flags = fcntl (fd, F_GETFL)) == -1 ||
      /* Must be O_PATH */
      ((fd_flags & O_PATH) != O_PATH) ||
      /* Must not be O_NOFOLLOW (because we want the target file) */
      ((fd_flags & O_NOFOLLOW) == O_PATH) ||
      /* Must be able to fstat */
      fstat (fd, &st_buf) < 0 ||
      /* Must be a regular file */
      (st_buf.st_mode & S_IFMT) != S_IFREG ||
      /* Must be able to read path from /proc/self/fd */
      /* This is an absolute and (at least at open time) symlink-expanded path */
      (symlink_size = readlink (proc_path, path_buffer, sizeof (path_buffer) - 1)) < 0)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             XDG_APP_PORTAL_ERROR, XDG_APP_PORTAL_ERROR_INVALID_ARGUMENT,
                                             "Invalid fd passed");
      return;
    }

  path_buffer[symlink_size] = 0;

  /* We open the parent directory and do the stat in that, so that we have
     trustworthy parent dev/ino for later verification. Otherwise the caller
     could later replace a parent with a symlink and make us read some other file */
  dirname = g_path_get_dirname (path_buffer);
  name = g_path_get_basename (path_buffer);
  dir_fd = open (dirname, O_CLOEXEC|O_PATH);

  if (fstat (dir_fd, &real_parent_st_buf) < 0 ||
      fstatat (dir_fd, name, &real_st_buf, AT_SYMLINK_NOFOLLOW) < 0 ||
      st_buf.st_dev != real_st_buf.st_dev ||
      st_buf.st_ino != real_st_buf.st_ino)
    {
      /* Don't leak any info about real file path existance, etc */
      g_dbus_method_invocation_return_error (invocation,
                                             XDG_APP_PORTAL_ERROR, XDG_APP_PORTAL_ERROR_INVALID_ARGUMENT,
                                             "Invalid fd passed");
      return;
    }

  g_debug ("portal_add %s", path_buffer);

  if (st_buf.st_dev == fuse_dev)
    {
      /* The passed in fd is on the fuse filesystem itself */
      g_autoptr(XdgAppDbEntry) old_entry = NULL;

      id = xdp_fuse_lookup_id_for_inode (st_buf.st_ino);
      g_debug ("path on fuse, id %s", id);
      if (id == NULL)
        {
          g_dbus_method_invocation_return_error (invocation,
                                                 XDG_APP_PORTAL_ERROR, XDG_APP_PORTAL_ERROR_INVALID_ARGUMENT,
                                                 "Invalid fd passed");
          return;
        }

      /* Don't lock the db before doing the fuse call above, because it takes takes a lock
         that can block something calling back, causing a deadlock on the db lock */

      AUTOLOCK(db);

      /* If the entry doesn't exist anymore, fail.  Also fail if not
         resuse_existing, because otherwise the user could use this to
         get a copy with permissions and thus escape later permission
         revocations */
      old_entry = xdg_app_db_lookup (db, id);
      if (old_entry == NULL ||
          !reuse_existing)
        {
          g_dbus_method_invocation_return_error (invocation,
                                                 XDG_APP_PORTAL_ERROR, XDG_APP_PORTAL_ERROR_INVALID_ARGUMENT,
                                                 "Invalid fd passed");
          return;
        }
    }
  else
    {
      {
        AUTOLOCK(db);

        id = do_create_doc (&real_parent_st_buf, path_buffer, reuse_existing, persistent);

        if (app_id[0] != '\0')
          {
            g_autoptr(XdgAppDbEntry) entry = NULL;
            XdpPermissionFlags perms =
              XDP_PERMISSION_FLAGS_GRANT_PERMISSIONS |
              XDP_PERMISSION_FLAGS_READ |
              XDP_PERMISSION_FLAGS_WRITE;
            {
              entry = xdg_app_db_lookup (db, id);

              /* If its a unique one its safe for the creator to
                 delete it at will */
              if (!reuse_existing)
                perms |= XDP_PERMISSION_FLAGS_DELETE;

              do_set_permissions (entry, id, app_id, perms);
            }
          }
      }

      /* Invalidate with lock dropped to avoid deadlock */
      xdp_fuse_invalidate_doc_app (id, NULL);
      if (app_id[0] != '\0')
        xdp_fuse_invalidate_doc_app (id, app_id);
    }

  g_dbus_method_invocation_return_value (invocation,
                                         g_variant_new ("(s)", id));
}
Exemple #5
0
/**
 * Convert a Scheme object to a GVariant that will serve as one of
 * the parameters of a call go g_dbus_proxy_call_....  Returns NULL
 * if it is unable to do the conversion.
 */
static GVariant *
scheme_object_to_parameter (Scheme_Object *obj, gchar *type)
{
  gchar *str;           // A temporary string

  // Special case: Array of bytes
  if (g_strcmp0 (type, "ay") == 0) 
    {
      if (SCHEME_BYTE_STRINGP (obj))
        {
          return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
                                            SCHEME_BYTE_STR_VAL (obj),
                                            SCHEME_BYTE_STRLEN_VAL (obj),
                                            sizeof (guchar));
        } // if it's a byte string
    } // array of bytes

  // Handle normal cases
  switch (type[0])
    {
      // Arrays
      case 'a':
        return scheme_object_to_array (obj, type);

      // Doubles
      case 'd':
        if (SCHEME_DBLP (obj))
          return g_variant_new ("d", SCHEME_DBL_VAL (obj));
        else if (SCHEME_FLTP (obj))
          return g_variant_new ("d", (double) SCHEME_FLT_VAL (obj));
        else if (SCHEME_INTP (obj))
          return g_variant_new ("d", (double) SCHEME_INT_VAL (obj));
        else if (SCHEME_RATIONALP (obj))
          return g_variant_new ("d", (double) scheme_rational_to_double (obj));
        else
          return NULL;

      // 32 bit integers
      case 'i':
        if (SCHEME_INTP (obj))
          return g_variant_new ("i", (int) SCHEME_INT_VAL (obj));
        else if (SCHEME_DBLP (obj))
          return g_variant_new ("i", (int) SCHEME_DBL_VAL (obj));
        else if (SCHEME_FLTP (obj))
          return g_variant_new ("i", (int) SCHEME_FLT_VAL (obj));
        else if (SCHEME_RATIONALP (obj))
          return g_variant_new ("i", (int) scheme_rational_to_double (obj));
        else 
          return NULL;

      // Strings
      case 's':
        str = scheme_object_to_string (obj);
        if (str == NULL)
          return NULL;
        return g_variant_new ("s", str);

      // 32 bit unsigned integers
      case 'u':
        if (SCHEME_INTP (obj))
          return g_variant_new ("u", (unsigned int) SCHEME_INT_VAL (obj));
        else
          return NULL;

      // Everything else is currently unsupported
      default:
        return NULL;
    } // switch
} // scheme_object_to_parameter
static void
selection_changed (GtkTreeSelection *selection,
                   GtkBuilder       *builder)
{
	GtkTreeModel *model;
	GtkTreeIter iter;
	char *locale;
	GDBusProxy *user;
	GVariant *variant;
	GError *error = NULL;
	char *object_path;

	if (gtk_tree_selection_get_selected (selection, &model, &iter) == FALSE) {
		g_warning ("No selected languages, this shouldn't happen");
		return;
	}

	user = NULL;
	variant = NULL;

	gtk_tree_model_get (model, &iter,
			    LOCALE_COL, &locale,
			    -1);

	if (proxy == NULL) {
		g_warning ("Would change the language to '%s', but no D-Bus connection available", locale);
		goto bail;
	}

	variant = g_dbus_proxy_call_sync (proxy,
					  "FindUserByName",
					  g_variant_new ("(s)", g_get_user_name ()),
					  G_DBUS_CALL_FLAGS_NONE,
					  -1,
					  NULL,
					  &error);
	if (variant == NULL) {
		g_warning ("Could not contact accounts service to look up '%s': %s",
			   g_get_user_name (), error->message);
		g_error_free (error);
		goto bail;
	}

	g_variant_get (variant, "(o)", &object_path);
	user = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
					      G_DBUS_PROXY_FLAGS_NONE,
					      NULL,
					      "org.freedesktop.Accounts",
					      object_path,
					      "org.freedesktop.Accounts.User",
					      NULL,
					      &error);
	g_free (object_path);

	if (user == NULL) {
		g_warning ("Could not create proxy for user '%s': %s",
			   g_variant_get_string (variant, NULL), error->message);
		g_error_free (error);
		goto bail;
	}
	g_variant_unref (variant);

	variant = g_dbus_proxy_call_sync (user,
					  "SetLanguage",
					  g_variant_new ("(s)", locale),
					  G_DBUS_CALL_FLAGS_NONE,
					  -1,
					  NULL,
					  &error);
	if (variant == NULL) {
		g_warning ("Failed to set the language '%s': %s", locale, error->message);
		g_error_free (error);
		goto bail;
	}

        /* Update the other tabs */
        formats_update_language (builder, locale);
        system_update_language (builder, locale);

	/* And done */

bail:
	if (variant != NULL)
		g_variant_unref (variant);
	if (user != NULL)
		g_object_unref (user);
	g_free (locale);
}
static void
assistant_prepare (GtkAssistant *ass, GtkWidget *page, EnrollData *data)
{
        const char *name;

        name = g_object_get_data (G_OBJECT (page), "name");
        if (name == NULL)
                return;

        if (g_str_equal (name, "enroll")) {
                GError *error = NULL;
                GtkBuilder *dialog = data->dialog;
                char *path;
                guint i;
                GVariant *result;
                gint num_enroll_stages;

                if (!claim (data, &error)) {
                        GtkWidget *d;
                        char *msg;

                        /* translators:
                         * The variable is the name of the device, for example:
                         * "Could you not access "Digital Persona U.are.U 4000/4000B" device */
                        msg = g_strdup_printf (_("Could not access '%s' device"), data->name);
                        d = get_error_dialog (msg, error->message, GTK_WINDOW (data->ass));
                        g_error_free (error);
                        gtk_dialog_run (GTK_DIALOG (d));
                        gtk_widget_destroy (d);
                        g_free (msg);

                        enroll_data_destroy (data);

                        return;
                }
                data->state = STATE_CLAIMED;

                result = g_dbus_connection_call_sync (connection,
                                                      "net.reactivated.Fprint",
                                                      g_dbus_proxy_get_object_path (data->device),
                                                      "org.freedesktop.DBus.Properties",
                                                      "Get",
                                                      g_variant_new ("(ss)", "net.reactivated.Fprint.Device", "num-enroll-stages"),
                                                      G_VARIANT_TYPE ("(v)"),
                                                      G_DBUS_CALL_FLAGS_NONE,
                                                      -1,
                                                      NULL,
                                                      &error);
                num_enroll_stages = 0;
                if (result) {
                        GVariant *v;

                        g_variant_get (result, "(v)", &v);
                        num_enroll_stages = g_variant_get_int32 (v);

                        g_variant_unref (result);
                        g_variant_unref (v);
                }

                if (num_enroll_stages < 1) {
                        GtkWidget *d;
                        char *msg;

                        /* translators:
                         * The variable is the name of the device, for example:
                         * "Could you not access "Digital Persona U.are.U 4000/4000B" device */
                        msg = g_strdup_printf (_("Could not access '%s' device"), data->name);
                        d = get_error_dialog (msg, "net.reactivated.Fprint.Error.Internal", GTK_WINDOW (data->ass));
                        gtk_dialog_run (GTK_DIALOG (d));
                        gtk_widget_destroy (d);
                        g_free (msg);

                        enroll_data_destroy (data);
                        return;
                }

                data->num_enroll_stages = num_enroll_stages;

                /* Hide the extra "bulbs" if not needed */
                for (i = MAX_ENROLL_STAGES; i > data->num_enroll_stages; i--) {
                        char *name;

                        name = g_strdup_printf ("image%d", i);
                        gtk_widget_hide (WID (name));
                        g_free (name);
                }
                /* And set the right image */
                {
                        char *filename;

                        filename = g_strdup_printf ("%s.png", data->finger);
                        path = g_build_filename (UM_PIXMAP_DIR, filename, NULL);
                        g_free (filename);
                }
                for (i = 1; i <= data->num_enroll_stages; i++) {
                        char *name;
                        name = g_strdup_printf ("image%d", i);
                        gtk_image_set_from_file (GTK_IMAGE (WID (name)), path);
                        g_free (name);
                }
                g_free (path);

                g_signal_connect (data->device, "g-signal", G_CALLBACK (device_signal_cb), data);

                if (!enroll_start (data, &error)) {
                        GtkWidget *d;
                        char *msg;

                        /* translators:
                         * The variable is the name of the device, for example:
                         * "Could you not access "Digital Persona U.are.U 4000/4000B" device */
                        msg = g_strdup_printf (_("Could not start finger capture on '%s' device"), data->name);
                        d = get_error_dialog (msg, error->message, GTK_WINDOW (data->ass));
                        g_error_free (error);
                        gtk_dialog_run (GTK_DIALOG (d));
                        gtk_widget_destroy (d);
                        g_free (msg);

                        enroll_data_destroy (data);

                        return;
                }
                data->state = STATE_ENROLLING;;
        } else {
                if (data->state == STATE_ENROLLING) {
                        enroll_stop (data, NULL);
                        data->state = STATE_CLAIMED;
                }
                if (data->state == STATE_CLAIMED) {
                        release (data, NULL);
                        data->state = STATE_NONE;
                }
        }
}
static void
handle_method_call (GDBusConnection       *connection,
                    const gchar           *sender,
                    const gchar           *object_path,
                    const gchar           *interface_name,
                    const gchar           *method_name,
                    GVariant              *parameters,
                    GDBusMethodInvocation *invocation,
                    gpointer               user_data)
{
  App *app = user_data;

  if (g_strcmp0 (method_name, "GetEvents") == 0)
    {
      GVariantBuilder builder;
      GHashTableIter hash_iter;
      CalendarAppointment *a;
      gint64 since;
      gint64 until;
      gboolean force_reload;
      gboolean window_changed;

      g_variant_get (parameters,
                     "(xxb)",
                     &since,
                     &until,
                     &force_reload);

      if (until < since)
        {
          g_dbus_method_invocation_return_dbus_error (invocation,
                                                      "org.gnome.Shell.CalendarServer.Error.Failed",
                                                      "until cannot be before since");
          goto out;
        }

      print_debug ("Handling GetEvents (since=%" G_GINT64_FORMAT ", until=%" G_GINT64_FORMAT ", force_reload=%s)",
                   since,
                   until,
                   force_reload ? "true" : "false");

      window_changed = FALSE;
      if (!(app->until == until && app->since == since))
        {
          GVariantBuilder *builder;
          GVariantBuilder *invalidated_builder;

          app->until = until;
          app->since = since;
          window_changed = TRUE;

          builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
          invalidated_builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
          g_variant_builder_add (builder, "{sv}",
                                 "Until", g_variant_new_int64 (app->until));
          g_variant_builder_add (builder, "{sv}",
                                 "Since", g_variant_new_int64 (app->since));
          g_dbus_connection_emit_signal (app->connection,
                                         NULL, /* destination_bus_name */
                                         "/org/gnome/Shell/CalendarServer",
                                         "org.freedesktop.DBus.Properties",
                                         "PropertiesChanged",
                                         g_variant_new ("(sa{sv}as)",
                                                        "org.gnome.Shell.CalendarServer",
                                                        builder,
                                                        invalidated_builder),
                                         NULL); /* GError** */
        }

      /* reload events if necessary */
      if (window_changed || force_reload || app->cache_invalid)
        {
          app_load_events (app);
        }

      /* The a{sv} is used as an escape hatch in case we want to provide more
       * information in the future without breaking ABI
       */
      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sssbxxa{sv})"));
      g_hash_table_iter_init (&hash_iter, app->appointments);
      while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &a))
        {
          GVariantBuilder extras_builder;
          GSList *l;

          for (l = a->occurrences; l; l = l->next)
            {
              CalendarOccurrence *o = l->data;
              time_t start_time = o->start_time;
              time_t end_time   = o->end_time;

              if ((start_time >= app->since &&
                   start_time < app->until) ||
                  (start_time <= app->since &&
                  (end_time - 1) > app->since))
                {
                  g_variant_builder_init (&extras_builder, G_VARIANT_TYPE ("a{sv}"));
                  g_variant_builder_add (&builder,
                                         "(sssbxxa{sv})",
                                         a->uid,
                                         a->summary != NULL ? a->summary : "",
                                         a->description != NULL ? a->description : "",
                                         (gboolean) a->is_all_day,
                                         (gint64) start_time,
                                         (gint64) end_time,
                                         extras_builder);
                }
            }
        }
      g_dbus_method_invocation_return_value (invocation,
                                             g_variant_new ("(a(sssbxxa{sv}))", &builder));
    }
  else
    {
      g_assert_not_reached ();
    }

 out:
  ;
}
static UserProperties *
user_properties_get (GDBusConnection *bus,
                     const gchar     *object_path)
{
        GVariant *result;
        GVariantIter *iter;
        gchar *key;
        GVariant *value;
        UserProperties *props;
        GError *error = NULL;

        result = g_dbus_connection_call_sync (bus,
                                              "org.freedesktop.Accounts",
                                              object_path,
                                              "org.freedesktop.DBus.Properties",
                                              "GetAll",
                                              g_variant_new ("(s)", "org.freedesktop.Accounts.User"),
                                              G_VARIANT_TYPE ("(a{sv})"),
                                              G_DBUS_CALL_FLAGS_NONE,
                                              -1,
                                              NULL,
                                              &error);
        if (!result) {
                g_debug ("Error calling GetAll() when retrieving properties for %s: %s", object_path, error->message);
                g_error_free (error);
                return NULL;
        }

        props = g_new0 (UserProperties, 1);
        g_variant_get (result, "(a{sv})", &iter);
        while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) {
                if (strcmp (key, "Uid") == 0) {
                        g_variant_get (value, "t", &props->uid);
                }
                else if (strcmp (key, "UserName") == 0) {
                        g_variant_get (value, "s", &props->user_name);
                }
                else if (strcmp (key, "RealName") == 0) {
                        g_variant_get (value, "s", &props->real_name);
                }
                else if (strcmp (key, "AccountType") == 0) {
                        g_variant_get (value, "i", &props->account_type);
                }
                else if (strcmp (key, "Email") == 0) {
                        g_variant_get (value, "s", &props->email);
                }
                else if (strcmp (key, "Language") == 0) {
                        g_variant_get (value, "s", &props->language);
                }
                else if (strcmp (key, "Location") == 0) {
                        g_variant_get (value, "s", &props->location);
                }
                else if (strcmp (key, "LoginFrequency") == 0) {
                        g_variant_get (value, "t", &props->login_frequency);
                }
                else if (strcmp (key, "IconFile") == 0) {
                        g_variant_get (value, "s", &props->icon_file);
                }
                else if (strcmp (key, "Locked") == 0) {
                        g_variant_get (value, "b", &props->locked);
                }
                else if (strcmp (key, "AutomaticLogin") == 0) {
                        g_variant_get (value, "b", &props->automatic_login);
                }
                else if (strcmp (key, "SystemAccount") == 0) {
                        g_variant_get (value, "b", &props->system_account);
                }
                else if (strcmp (key, "PasswordMode") == 0) {
                        g_variant_get (value, "i", &props->password_mode);
                }
                else if (strcmp (key, "PasswordHint") == 0) {
                        g_variant_get (value, "s", &props->password_hint);
                }
                else if (strcmp (key, "HomeDirectory") == 0) {
                        /* ignore */
                }
                else if (strcmp (key, "Shell") == 0) {
                        /* ignore */
                }
                else {
                        g_debug ("unhandled property %s", key);
                }
        }
  
        g_variant_iter_free (iter);
        g_variant_unref (result);

        return props;
}
Exemple #10
0
static GVariant *
parse_dns_ns (DNS_RECORD *rec)
{
  return g_variant_new ("(s)", rec->Data.NS.pNameHost);
}
Exemple #11
0
EVENTD_EXPORT
FilenameProcessResult
evhelpers_filename_process(const Filename *filename, EventdEvent *event, const gchar *subdir, gchar **ret_uri, GVariant **ret_data)
{
    g_return_val_if_fail(filename != NULL, FILENAME_PROCESS_RESULT_NONE);
    g_return_val_if_fail(event != NULL, FILENAME_PROCESS_RESULT_NONE);
    g_return_val_if_fail(subdir != NULL, FILENAME_PROCESS_RESULT_NONE);
    g_return_val_if_fail(ret_uri != NULL, FILENAME_PROCESS_RESULT_NONE);
    g_return_val_if_fail(ret_data != NULL, FILENAME_PROCESS_RESULT_NONE);

    gchar *uri = NULL;

    if ( filename->data_name != NULL )
    {
        GVariant *data;
        data = eventd_event_get_data(event, filename->data_name);
        if ( data == NULL )
            return FILENAME_PROCESS_RESULT_NONE;
        if ( g_variant_is_of_type(data, G_VARIANT_TYPE_STRING) )
            uri = g_variant_dup_string(data, NULL);
        else if ( g_variant_is_of_type(data, G_VARIANT_TYPE("(msmsv)")) )
        {
            *ret_data = g_variant_ref(data);
            return FILENAME_PROCESS_RESULT_DATA;
        }
        else
            return FILENAME_PROCESS_RESULT_NONE;
    }
    else if ( filename->file_uri != NULL )
        uri = evhelpers_format_string_get_string(filename->file_uri, event, NULL, NULL);
    else
        g_return_val_if_reached(FILENAME_PROCESS_RESULT_NONE);

    if ( uri == NULL )
        return FILENAME_PROCESS_RESULT_NONE;
    if ( *uri == '\0' )
    {
        g_free(uri);
        return FILENAME_PROCESS_RESULT_NONE;
    }

    if ( g_str_has_prefix(uri, "data:") )
    {
        gchar *mime_type = uri + strlen("data:");
        if ( _evhelpers_filename_check_data_base64_prefix(mime_type) )
        {
            gchar *c;
            guchar *data;
            gsize length;

            /* We checked for ";base64," already */
            c = g_utf8_strchr(mime_type, -1, ',');
            *c = '\0';

            data = g_base64_decode(c + 1, &length);

            c = g_utf8_strchr(mime_type, c - mime_type, ';');
            *c++ = '\0';

            if ( *mime_type == '\0' )
                mime_type = NULL;

            if ( *c == '\0' )
                c = NULL;

            *ret_data = g_variant_new("(msmsv)", mime_type, c, g_variant_new_from_data(G_VARIANT_TYPE_BYTESTRING, data, length, FALSE, g_free, data));
            g_free(uri);
            return FILENAME_PROCESS_RESULT_DATA;
        }
    }
    else if ( g_str_has_prefix(uri, "file://") )
    {
        const gchar *p = uri + strlen("file://");
        if ( ! g_path_is_absolute(p) )
        {
            gchar *tmp = uri;
            if ( g_path_is_absolute(subdir) )
                uri = g_strconcat("file://", subdir, G_DIR_SEPARATOR_S, p, NULL);
            else
                uri = g_strconcat("file://", g_get_user_data_dir(), G_DIR_SEPARATOR_S PACKAGE_NAME G_DIR_SEPARATOR_S, subdir, G_DIR_SEPARATOR_S, p, NULL);
            g_free(tmp);
            p = uri + strlen("file://");
        }
        if ( g_file_test(p, G_FILE_TEST_IS_REGULAR) )
        {
            *ret_uri = uri;
            return FILENAME_PROCESS_RESULT_URI;
        }
    }
    else if ( g_str_has_prefix(uri, "theme:") )
    {
        *ret_uri = uri;
        return FILENAME_PROCESS_RESULT_THEME;
    }

    g_free(uri);

    return FILENAME_PROCESS_RESULT_NONE;
}
Exemple #12
0
int dt_init(int argc, char *argv[], const int init_gui)
{
  // make everything go a lot faster.
  _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
#ifndef __APPLE__
  _dt_sigsegv_old_handler = signal(SIGSEGV,&_dt_sigsegv_handler);
#endif

#ifndef __SSE2__
  fprintf(stderr, "[dt_init] unfortunately we depend on SSE2 instructions at this time.\n");
  fprintf(stderr, "[dt_init] please contribute a backport patch (or buy a newer processor).\n");
  return 1;
#endif

#ifdef M_MMAP_THRESHOLD
  mallopt(M_MMAP_THRESHOLD,128*1024) ; /* use mmap() for large allocations */
#endif

  bindtextdomain (GETTEXT_PACKAGE, DARKTABLE_LOCALEDIR);
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
  textdomain (GETTEXT_PACKAGE);


  // init all pointers to 0:
  memset(&darktable, 0, sizeof(darktable_t));

  darktable.progname = argv[0];

  // database
  gchar *dbfilename_from_command = NULL;
  char *datadir_from_command = NULL;
  char *moduledir_from_command = NULL;
  char *tmpdir_from_command = NULL;
  char *configdir_from_command = NULL;
  char *cachedir_from_command = NULL;

  darktable.num_openmp_threads = 1;
#ifdef _OPENMP
  darktable.num_openmp_threads = omp_get_num_procs();
#endif
  darktable.unmuted = 0;
  GSList *images_to_load = NULL;
  for(int k=1; k<argc; k++)
  {
    if(argv[k][0] == '-')
    {
      if(!strcmp(argv[k], "--help"))
      {
        return usage(argv[0]);
      }
      if(!strcmp(argv[k], "-h"))
      {
        return usage(argv[0]);
      }
      else if(!strcmp(argv[k], "--version"))
      {
        printf("this is "PACKAGE_STRING"\ncopyright (c) 2009-2013 johannes hanika\n"PACKAGE_BUGREPORT"\n");
        return 1;
      }
      else if(!strcmp(argv[k], "--library"))
      {
        dbfilename_from_command = argv[++k];
      }
      else if(!strcmp(argv[k], "--datadir"))
      {
        datadir_from_command = argv[++k];
      }
      else if(!strcmp(argv[k], "--moduledir"))
      {
        moduledir_from_command = argv[++k];
      }
      else if(!strcmp(argv[k], "--tmpdir"))
      {
        tmpdir_from_command = argv[++k];
      }
      else if(!strcmp(argv[k], "--configdir"))
      {
        configdir_from_command = argv[++k];
      }
      else if(!strcmp(argv[k], "--cachedir"))
      {
        cachedir_from_command = argv[++k];
      }
      else if(!strcmp(argv[k], "--localedir"))
      {
        bindtextdomain (GETTEXT_PACKAGE, argv[++k]);
      }
      else if(argv[k][1] == 'd' && argc > k+1)
      {
        if(!strcmp(argv[k+1], "all"))             darktable.unmuted = 0xffffffff;   // enable all debug information
        else if(!strcmp(argv[k+1], "cache"))      darktable.unmuted |= DT_DEBUG_CACHE;   // enable debugging for lib/film/cache module
        else if(!strcmp(argv[k+1], "control"))    darktable.unmuted |= DT_DEBUG_CONTROL; // enable debugging for scheduler module
        else if(!strcmp(argv[k+1], "dev"))        darktable.unmuted |= DT_DEBUG_DEV; // develop module
        else if(!strcmp(argv[k+1], "fswatch"))    darktable.unmuted |= DT_DEBUG_FSWATCH; // fswatch module
        else if(!strcmp(argv[k+1], "camctl"))     darktable.unmuted |= DT_DEBUG_CAMCTL; // camera control module
        else if(!strcmp(argv[k+1], "perf"))       darktable.unmuted |= DT_DEBUG_PERF; // performance measurements
        else if(!strcmp(argv[k+1], "pwstorage"))  darktable.unmuted |= DT_DEBUG_PWSTORAGE; // pwstorage module
        else if(!strcmp(argv[k+1], "opencl"))     darktable.unmuted |= DT_DEBUG_OPENCL;    // gpu accel via opencl
        else if(!strcmp(argv[k+1], "sql"))        darktable.unmuted |= DT_DEBUG_SQL; // SQLite3 queries
        else if(!strcmp(argv[k+1], "memory"))     darktable.unmuted |= DT_DEBUG_MEMORY; // some stats on mem usage now and then.
        else if(!strcmp(argv[k+1], "lighttable")) darktable.unmuted |= DT_DEBUG_LIGHTTABLE; // lighttable related stuff.
        else if(!strcmp(argv[k+1], "nan"))        darktable.unmuted |= DT_DEBUG_NAN; // check for NANs when processing the pipe.
        else return usage(argv[0]);
        k ++;
      }
      else if(argv[k][1] == 't' && argc > k+1)
      {
        darktable.num_openmp_threads = CLAMP(atol(argv[k+1]), 1, 100);
        printf("[dt_init] using %d threads for openmp parallel sections\n", darktable.num_openmp_threads);
        k ++;
      }
    }
#ifndef MAC_INTEGRATION
    else
    {
      images_to_load = g_slist_append(images_to_load, argv[k]);
    }
#endif
  }

  if(darktable.unmuted & DT_DEBUG_MEMORY)
  {
    fprintf(stderr, "[memory] at startup\n");
    dt_print_mem_usage();
  }

#ifdef _OPENMP
  omp_set_num_threads(darktable.num_openmp_threads);
#endif
  dt_loc_init_datadir(datadir_from_command);
  dt_loc_init_plugindir(moduledir_from_command);
  if(dt_loc_init_tmp_dir(tmpdir_from_command))
  {
    printf(_("ERROR : invalid temporary directory : %s\n"),darktable.tmpdir);
    return usage(argv[0]);
  }
  dt_loc_init_user_config_dir(configdir_from_command);
  dt_loc_init_user_cache_dir(cachedir_from_command);

#if !GLIB_CHECK_VERSION(2, 35, 0)
  g_type_init();
#endif

  // does not work, as gtk is not inited yet.
  // even if it were, it's a super bad idea to invoke gtk stuff from
  // a signal handler.
  /* check cput caps */
  // dt_check_cpu(argc,argv);

#ifdef HAVE_GEGL
  char geglpath[DT_MAX_PATH_LEN];
  char datadir[DT_MAX_PATH_LEN];
  dt_loc_get_datadir(datadir, DT_MAX_PATH_LEN);
  snprintf(geglpath, DT_MAX_PATH_LEN, "%s/gegl:/usr/lib/gegl-0.0", datadir);
  (void)setenv("GEGL_PATH", geglpath, 1);
  gegl_init(&argc, &argv);
#endif

  // thread-safe init:
  dt_exif_init();
  char datadir[DT_MAX_PATH_LEN];
  dt_loc_get_user_config_dir (datadir,DT_MAX_PATH_LEN);
  char filename[DT_MAX_PATH_LEN];
  snprintf(filename, DT_MAX_PATH_LEN, "%s/darktablerc", datadir);

  // intialize the config backend. this needs to be done first...
  darktable.conf = (dt_conf_t *)malloc(sizeof(dt_conf_t));
  memset(darktable.conf, 0, sizeof(dt_conf_t));
  dt_conf_init(darktable.conf, filename);

  // set the interface language
  const gchar* lang = dt_conf_get_string("ui_last/gui_language");
  if(lang != NULL && lang[0] != '\0')
  {
    if(setlocale(LC_ALL, lang) != NULL)
      gtk_disable_setlocale();
  }

  // initialize the database
  darktable.db = dt_database_init(dbfilename_from_command);
  if(darktable.db == NULL)
  {
    printf("ERROR : cannot open database\n");
    return 1;
  }
  else if(dt_database_get_already_locked(darktable.db))
  {
    // send the images to the other instance via dbus
    if(images_to_load)
    {
      GSList *p = images_to_load;

      // get a connection!
      GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SESSION,NULL, NULL);

      while (p != NULL)
      {
        // make the filename absolute ...
        gchar *filename = dt_make_path_absolute((gchar*)p->data);
        if(filename == NULL) continue;
        // ... and send it to the running instance of darktable
        g_dbus_connection_call_sync(connection,
                                    "org.darktable.service",
                                    "/darktable",
                                    "org.darktable.service.Remote",
                                    "Open",
                                    g_variant_new ("(s)", filename),
                                    NULL,
                                    G_DBUS_CALL_FLAGS_NONE,
                                    -1,
                                    NULL,
                                    NULL);
        p = g_slist_next(p);
        g_free(filename);
      }

      g_slist_free(images_to_load);
      g_object_unref(connection);
    }

    return 1;
  }

  // Initialize the signal system
  darktable.signals = dt_control_signal_init();

  // Initialize the filesystem watcher
  darktable.fswatch=dt_fswatch_new();

#ifdef HAVE_GPHOTO2
  // Initialize the camera control
  darktable.camctl=dt_camctl_new();
#endif

  // get max lighttable thumbnail size:
  darktable.thumbnail_width  = CLAMPS(dt_conf_get_int("plugins/lighttable/thumbnail_width"),  200, 3000);
  darktable.thumbnail_height = CLAMPS(dt_conf_get_int("plugins/lighttable/thumbnail_height"), 200, 3000);
  // and make sure it can be mip-mapped all the way from mip4 to mip0
  darktable.thumbnail_width  /= 16;
  darktable.thumbnail_width  *= 16;
  darktable.thumbnail_height /= 16;
  darktable.thumbnail_height *= 16;

  // Initialize the password storage engine
  darktable.pwstorage=dt_pwstorage_new();

  // FIXME: move there into dt_database_t
  dt_pthread_mutex_init(&(darktable.db_insert), NULL);
  dt_pthread_mutex_init(&(darktable.plugin_threadsafe), NULL);
  dt_pthread_mutex_init(&(darktable.capabilities_threadsafe), NULL);
  darktable.control = (dt_control_t *)malloc(sizeof(dt_control_t));
  memset(darktable.control, 0, sizeof(dt_control_t));
  if(init_gui)
  {
    dt_control_init(darktable.control);
  }
  else
  {
    // this is in memory, so schema can't exist yet.
    if(dbfilename_from_command && !strcmp(dbfilename_from_command, ":memory:"))
    {
      dt_control_create_database_schema();
      dt_gui_presets_init(); // also init preset db schema.
    }
    darktable.control->running = 0;
    darktable.control->accelerators = NULL;
    dt_pthread_mutex_init(&darktable.control->run_mutex, NULL);
  }

  // initialize collection query
  darktable.collection_listeners = NULL;
  darktable.collection = dt_collection_new(NULL);

  /* initialize sellection */
  darktable.selection = dt_selection_new();

  /* capabilities set to NULL */
  darktable.capabilities = NULL;

#ifdef HAVE_GRAPHICSMAGICK
  /* GraphicsMagick init */
  InitializeMagick(darktable.progname);
#endif

  darktable.opencl = (dt_opencl_t *)malloc(sizeof(dt_opencl_t));
  memset(darktable.opencl, 0, sizeof(dt_opencl_t));
  dt_opencl_init(darktable.opencl, argc, argv);

  darktable.blendop = (dt_blendop_t *)malloc(sizeof(dt_blendop_t));
  memset(darktable.blendop, 0, sizeof(dt_blendop_t));
  dt_develop_blend_init(darktable.blendop);

  darktable.points = (dt_points_t *)malloc(sizeof(dt_points_t));
  memset(darktable.points, 0, sizeof(dt_points_t));
  dt_points_init(darktable.points, dt_get_num_threads());

  // must come before mipmap_cache, because that one will need to access
  // image dimensions stored in here:
  darktable.image_cache = (dt_image_cache_t *)malloc(sizeof(dt_image_cache_t));
  memset(darktable.image_cache, 0, sizeof(dt_image_cache_t));
  dt_image_cache_init(darktable.image_cache);

  darktable.mipmap_cache = (dt_mipmap_cache_t *)malloc(sizeof(dt_mipmap_cache_t));
  memset(darktable.mipmap_cache, 0, sizeof(dt_mipmap_cache_t));
  dt_mipmap_cache_init(darktable.mipmap_cache);

  // The GUI must be initialized before the views, because the init()
  // functions of the views depend on darktable.control->accels_* to register
  // their keyboard accelerators

  if(init_gui)
  {
    darktable.gui = (dt_gui_gtk_t *)malloc(sizeof(dt_gui_gtk_t));
    memset(darktable.gui,0,sizeof(dt_gui_gtk_t));
    if(dt_gui_gtk_init(darktable.gui, argc, argv)) return 1;
    dt_bauhaus_init();
  }
  else darktable.gui = NULL;

  darktable.view_manager = (dt_view_manager_t *)malloc(sizeof(dt_view_manager_t));
  memset(darktable.view_manager, 0, sizeof(dt_view_manager_t));
  dt_view_manager_init(darktable.view_manager);

  // load the darkroom mode plugins once:
  dt_iop_load_modules_so();

  if(init_gui)
  {
    darktable.lib = (dt_lib_t *)malloc(sizeof(dt_lib_t));
    memset(darktable.lib, 0, sizeof(dt_lib_t));
    dt_lib_init(darktable.lib);

    dt_control_load_config(darktable.control);
    g_strlcpy(darktable.control->global_settings.dbname, filename, 512); // overwrite if relocated.
  }
  darktable.imageio = (dt_imageio_t *)malloc(sizeof(dt_imageio_t));
  memset(darktable.imageio, 0, sizeof(dt_imageio_t));
  dt_imageio_init(darktable.imageio);

  if(init_gui)
  {
    // Loading the keybindings
    char keyfile[DT_MAX_PATH_LEN];

    // First dump the default keymapping
    snprintf(keyfile, DT_MAX_PATH_LEN, "%s/keyboardrc_default", datadir);
    gtk_accel_map_save(keyfile);

    // Removing extraneous semi-colons from the default keymap
    strip_semicolons_from_keymap(keyfile);

    // Then load any modified keys if available
    snprintf(keyfile, DT_MAX_PATH_LEN, "%s/keyboardrc", datadir);
    if(g_file_test(keyfile, G_FILE_TEST_EXISTS))
      gtk_accel_map_load(keyfile);
    else
      gtk_accel_map_save(keyfile); // Save the default keymap if none is present

    // I doubt that connecting to dbus for darktable-cli makes sense
    darktable.dbus = dt_dbus_init();

    // initialize undo struct
    darktable.undo = dt_undo_init();

    // load image(s) specified on cmdline
    int id = 0;
    if(images_to_load)
    {
      // If only one image is listed, attempt to load it in darkroom
      gboolean load_in_dr = (g_slist_next(images_to_load) == NULL);
      GSList *p = images_to_load;

      while (p != NULL)
      {
        // don't put these function calls into MAX(), the macro will evaluate
        // it twice (and happily deadlock, in this particular case)
        int newid = dt_load_from_string((gchar*)p->data, load_in_dr);
        id = MAX(id, newid);
        p = g_slist_next(p);
      }

      if (!load_in_dr || id == 0)
        dt_ctl_switch_mode_to(DT_LIBRARY);

      g_slist_free(images_to_load);
    }
    else
      dt_ctl_switch_mode_to(DT_LIBRARY);
  }

  /* start the indexer background job */
  dt_control_start_indexer();

  if(darktable.unmuted & DT_DEBUG_MEMORY)
  {
    fprintf(stderr, "[memory] after successful startup\n");
    dt_print_mem_usage();
  }

  return 0;
}
Exemple #13
0
/**
 * fwupd_release_to_variant:
 * @release: A #FwupdRelease
 *
 * Creates a GVariant from the release data.
 *
 * Returns: the GVariant, or %NULL for error
 *
 * Since: 1.0.0
 **/
GVariant *
fwupd_release_to_variant (FwupdRelease *release)
{
	FwupdReleasePrivate *priv = GET_PRIVATE (release);
	GVariantBuilder builder;

	g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL);

	/* create an array with all the metadata in */
	g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
	if (priv->remote_id != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_REMOTE_ID,
				       g_variant_new_string (priv->remote_id));
	}
	if (priv->appstream_id != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_APPSTREAM_ID,
				       g_variant_new_string (priv->appstream_id));
	}
	if (priv->filename != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_FILENAME,
				       g_variant_new_string (priv->filename));
	}
	if (priv->protocol != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_PROTOCOL,
				       g_variant_new_string (priv->protocol));
	}
	if (priv->license != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_LICENSE,
				       g_variant_new_string (priv->license));
	}
	if (priv->name != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_NAME,
				       g_variant_new_string (priv->name));
	}
	if (priv->size != 0) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_SIZE,
				       g_variant_new_uint64 (priv->size));
	}
	if (priv->summary != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_SUMMARY,
				       g_variant_new_string (priv->summary));
	}
	if (priv->description != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_DESCRIPTION,
				       g_variant_new_string (priv->description));
	}
	if (priv->checksums->len > 0) {
		g_autoptr(GString) str = g_string_new ("");
		for (guint i = 0; i < priv->checksums->len; i++) {
			const gchar *checksum = g_ptr_array_index (priv->checksums, i);
			g_string_append_printf (str, "%s,", checksum);
		}
		if (str->len > 0)
			g_string_truncate (str, str->len - 1);
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_CHECKSUM,
				       g_variant_new_string (str->str));
	}
	if (priv->uri != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_URI,
				       g_variant_new_string (priv->uri));
	}
	if (priv->homepage != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_HOMEPAGE,
				       g_variant_new_string (priv->homepage));
	}
	if (priv->details_url != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_DETAILS_URL,
				       g_variant_new_string (priv->details_url));
	}
	if (priv->source_url != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_SOURCE_URL,
				       g_variant_new_string (priv->source_url));
	}
	if (priv->version != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_VERSION,
				       g_variant_new_string (priv->version));
	}
	if (priv->vendor != NULL) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_VENDOR,
				       g_variant_new_string (priv->vendor));
	}
	if (priv->flags != 0) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_TRUST_FLAGS,
				       g_variant_new_uint64 (priv->flags));
	}
	if (g_hash_table_size (priv->metadata) > 0) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_METADATA,
				       _hash_kv_to_variant (priv->metadata));
	}
	if (priv->install_duration > 0) {
		g_variant_builder_add (&builder, "{sv}",
				       FWUPD_RESULT_KEY_INSTALL_DURATION,
				       g_variant_new_uint32 (priv->install_duration));
	}
	return g_variant_new ("a{sv}", &builder);
}
Exemple #14
0
/**
 * udisks_daemon_util_get_caller_uid_sync:
 * @daemon: A #UDisksDaemon.
 * @invocation: A #GDBusMethodInvocation.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @out_uid: (out): Return location for resolved uid or %NULL.
 * @out_gid: (out) (allow-none): Return location for resolved gid or %NULL.
 * @out_user_name: (out) (allow-none): Return location for resolved user name or %NULL.
 * @error: Return location for error.
 *
 * Gets the UNIX user id (and possibly group id and user name) of the
 * peer represented by @invocation.
 *
 * Returns: %TRUE if the user id (and possibly group id) was obtained, %FALSE otherwise
 */
gboolean
udisks_daemon_util_get_caller_uid_sync (UDisksDaemon            *daemon,
                                        GDBusMethodInvocation   *invocation,
                                        GCancellable            *cancellable,
                                        uid_t                   *out_uid,
                                        gid_t                   *out_gid,
                                        gchar                  **out_user_name,
                                        GError                 **error)
{
  gboolean ret;
  const gchar *caller;
  GVariant *value;
  GError *local_error;
  uid_t uid;

  /* TODO: cache this on @daemon */

  ret = FALSE;

  caller = g_dbus_method_invocation_get_sender (invocation);

  local_error = NULL;
  value = g_dbus_connection_call_sync (g_dbus_method_invocation_get_connection (invocation),
                                       "org.freedesktop.DBus",  /* bus name */
                                       "/org/freedesktop/DBus", /* object path */
                                       "org.freedesktop.DBus",  /* interface */
                                       "GetConnectionUnixUser", /* method */
                                       g_variant_new ("(s)", caller),
                                       G_VARIANT_TYPE ("(u)"),
                                       G_DBUS_CALL_FLAGS_NONE,
                                       -1, /* timeout_msec */
                                       cancellable,
                                       &local_error);
  if (value == NULL)
    {
      g_set_error (error,
                   UDISKS_ERROR,
                   UDISKS_ERROR_FAILED,
                   "Error determining uid of caller %s: %s (%s, %d)",
                   caller,
                   local_error->message,
                   g_quark_to_string (local_error->domain),
                   local_error->code);
      g_error_free (local_error);
      goto out;
    }

  {
    G_STATIC_ASSERT (sizeof (uid_t) == sizeof (guint32));
  }

  g_variant_get (value, "(u)", &uid);
  if (out_uid != NULL)
    *out_uid = uid;

  if (out_gid != NULL || out_user_name != NULL)
    {
      struct passwd pwstruct;
      gchar pwbuf[8192];
      struct passwd *pw = NULL;
      int rc;

      rc = getpwuid_r (uid, &pwstruct, pwbuf, sizeof pwbuf, &pw);
      if (rc == 0 && pw == NULL)
        {
          g_set_error (error,
                       UDISKS_ERROR,
                       UDISKS_ERROR_FAILED,
                       "User with uid %d does not exist", (gint) uid);
          goto out;
        }
      else if (pw == NULL)
        {
          g_set_error (error,
                       UDISKS_ERROR,
                       UDISKS_ERROR_FAILED,
                       "Error looking up passwd struct for uid %d: %m", (gint) uid);
          goto out;
        }
      if (out_gid != NULL)
        *out_gid = pw->pw_gid;
      if (out_user_name != NULL)
        *out_user_name = g_strdup (pwstruct.pw_name);
    }

  ret = TRUE;

 out:
  return ret;
}
Exemple #15
0
static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
		const struct sr_channel_group *cg)
{
	struct dev_context *devc = sdi->priv;
	struct parport *port;
	int ret, i, ch = -1;

	if (cg) /* sr_config_get will validate cg using config_list */
		ch = ((struct sr_channel *)cg->channels->data)->index;

	ret = SR_OK;
	switch (key) {
	case SR_CONF_CONN:
		port = sdi->conn;
		*data = g_variant_new_string(port->name);
		break;
	case SR_CONF_LIMIT_FRAMES:
		*data = g_variant_new_uint64(devc->frame_limit);
		break;
	case SR_CONF_SAMPLERATE:
		*data = g_variant_new_uint64(samplerates[devc->rate]);
		break;
	case SR_CONF_TRIGGER_SOURCE:
		i = reverse_map(devc->cctl[0] & 0xC0, trigger_sources_map,
				ARRAY_SIZE(trigger_sources_map));
		if (i == -1)
			ret = SR_ERR;
		else
			*data = g_variant_new_string(trigger_sources[i]);
		break;
	case SR_CONF_TRIGGER_SLOPE:
		if (devc->edge >= ARRAY_SIZE(trigger_slopes))
			ret = SR_ERR;
		else
			*data = g_variant_new_string(trigger_slopes[devc->edge]);
		break;
	case SR_CONF_BUFFERSIZE:
		*data = g_variant_new_uint64(buffersizes[devc->last_step]);
		break;
	case SR_CONF_VDIV:
		if (ch == -1) {
			ret = SR_ERR_CHANNEL_GROUP;
		} else {
			i = reverse_map(devc->cctl[ch] & 0x33, vdivs_map,
					ARRAY_SIZE(vdivs_map));
			if (i == -1)
				ret = SR_ERR;
			else
				*data = g_variant_new("(tt)", vdivs[i][0],
						      vdivs[i][1]);
		}
		break;
	case SR_CONF_COUPLING:
		if (ch == -1) {
			ret = SR_ERR_CHANNEL_GROUP;
		} else {
			i = reverse_map(devc->cctl[ch] & 0x0C, coupling_map,
					ARRAY_SIZE(coupling_map));
			if (i == -1)
				ret = SR_ERR;
			else
				*data = g_variant_new_string(coupling[i]);
		}
		break;
	case SR_CONF_PROBE_FACTOR:
		if (ch == -1)
			ret = SR_ERR_CHANNEL_GROUP;
		else
			*data = g_variant_new_uint64(devc->probe[ch]);
		break;
	default:
		ret = SR_ERR_NA;
	}

	return ret;
}
Exemple #16
0
static void
indicator_workrave_start(IndicatorWorkrave *self)
{
  IndicatorWorkravePrivate *priv = INDICATOR_WORKRAVE_GET_PRIVATE(self);

  if (priv->alive)
    {
      return;
    }

  priv->owner_id = g_bus_own_name(G_BUS_TYPE_SESSION,
                                  DBUS_NAME,
                                  G_BUS_NAME_OWNER_FLAGS_NONE,
                                  on_bus_acquired,
                                  NULL,
                                  NULL,
                                  self,
                                  NULL);

  GError *error = NULL;

  if (error == NULL)
    {
      GVariant *result = g_dbus_proxy_call_sync(priv->workrave_ui_proxy,
                                                "Embed",
                                                g_variant_new("(bs)", TRUE, DBUS_NAME),
                                                G_DBUS_CALL_FLAGS_NONE,
                                                -1,
                                                NULL,
                                                &error);

      if (error != NULL)
        {
          g_warning("Could not request embedding for %s: %s", WORKRAVE_INDICATOR_SERVICE_NAME, error->message);
        }
      else
        {
          if (result != NULL)
            {
              g_variant_unref(result);
            }
        }
    }

  if (error == NULL)
    {
      GVariant *result = g_dbus_proxy_call_sync(priv->workrave_ui_proxy,
                                                "GetTrayIconEnabled",
                                                NULL,
                                                G_DBUS_CALL_FLAGS_NONE,
                                                -1,
                                                NULL,
                                                &error);

      if (error != NULL)
        {
          g_warning("Could not request tray icon enabled for %s: %s", WORKRAVE_INDICATOR_SERVICE_NAME, error->message);
        }
      else
        {
          if (result != NULL)
            {
              g_variant_get(result, "(b)", &priv->force_icon);
              g_variant_unref(result);
            }
        }
    }

  if (error == NULL)
    {
      GVariant *result = g_dbus_proxy_call_sync(priv->workrave_core_proxy,
                                                "GetOperationMode",
                                                NULL,
                                                G_DBUS_CALL_FLAGS_NONE,
                                                -1,
                                                NULL,
                                                &error);

      if (error != NULL)
        {
          g_warning("Could not request operation mode for %s: %s", WORKRAVE_INDICATOR_SERVICE_NAME, error->message);
        }
      else
        {
          gchar *mode;
          g_variant_get(result, "(s)", &mode);
          workrave_timerbox_set_operation_mode(priv->timerbox, mode);
          g_variant_unref(result);
        }
    }

  if (error == NULL)
    {
      priv->timer = g_timeout_add_seconds(10, on_timer, self);
      priv->alive = TRUE;
      priv->update_count = 0;
    }
  else
    {
      g_error_free(error);
    }
}
BT_EXPORT_API int bluetooth_telephony_indicate_outgoing_call(
			const char *ph_number, unsigned int call_id,
			unsigned int bt_audio)
{
	GVariant *reply = NULL;
	GError *err = NULL;
	const char *path = telephony_info.call_path;
	int ret;
	GDBusConnection *conn;
	BT_DBG("+");

	conn  = _bt_init_system_gdbus_conn();

	BT_TELEPHONY_CHECK_INITIALIZED();
	BT_TELEPHONY_CHECK_ENABLED();

	if (NULL == ph_number)
		return BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM;

	reply = g_dbus_connection_call_sync(conn,
					HFP_AGENT_SERVICE,
					HFP_AGENT_PATH,
					HFP_AGENT_INTERFACE,
					"OutgoingCall",
					g_variant_new("(ssi)",
					path,
					ph_number,
					call_id),
					NULL,
					G_DBUS_CALL_FLAGS_NONE,
					-1,
					NULL,
					&err);

	if (!reply) {
		BT_ERR("Error returned in method call\n");
		if (err) {
			ret = __bt_telephony_get_error(err->message);
			g_clear_error(&err);
			return ret;
		}
		return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
	}

	g_free(reply);

	telephony_info.call_count++;
	BT_DBG(" ag_info.ag_call_count = [%d]", telephony_info.call_count);

	if (bt_audio) {
		if (!bluetooth_telephony_is_sco_connected()) {
			ret = bluetooth_telephony_audio_open();
			if (ret != 0) {
				BT_ERR(" Audio connection call Failed = %d",
									ret);
				return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
			}
		}
	}

	BT_DBG("-");
	return BLUETOOTH_TELEPHONY_ERROR_NONE;
}
Exemple #18
0
static HRESULT
get_connection_from_udev_or_odccm(SynceInfo *info, int *sockfd)
{
  GError *error = NULL;
  GDBusProxy *dbus_proxy = NULL;
  GDBusProxy *dev_proxy = NULL;
  gboolean dccm_running = FALSE;
  gchar *unix_path = NULL;
  gint fd = -1;
  GVariant *ret = NULL;
  const gchar *service = NULL;
  const gchar *dev_iface = NULL;
  const gchar *dccm_name = NULL;
  HRESULT result = E_FAIL;

  /* Ensure that e.g. SYNCE_DCCM_ERROR is registered using g_dbus_error_register_error() */
  synce_glib_init();

#if ENABLE_ODCCM_SUPPORT
  const gchar *transport = synce_info_get_transport(info);
  if (strcmp(transport, "odccm") == 0) {
    service = ODCCM_SERVICE;
    dev_iface = ODCCM_DEV_IFACE;
    dccm_name = "odccm";
  } else 
#endif
  {
    service = DCCM_SERVICE;
    dev_iface = DCCM_DEV_IFACE;
    dccm_name = "dccm";
  }

#if !GLIB_CHECK_VERSION (2, 36, 0)
  g_type_init();
#endif

  dbus_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
					      G_DBUS_PROXY_FLAGS_NONE,
					      NULL, /* GDBusInterfaceInfo */
					      DBUS_SERVICE,
					      DBUS_PATH,
					      DBUS_IFACE,
					      NULL, /* GCancellable */
					      &error);
  if (dbus_proxy == NULL) {
    g_warning("%s: Failed to get dbus proxy object: %s", G_STRFUNC, error->message);
    goto ERROR;
  }

  ret = g_dbus_proxy_call_sync (dbus_proxy,
				"NameHasOwner",
				g_variant_new ("(s)", service),
				G_DBUS_CALL_FLAGS_NONE,
				-1,
				NULL,
				&error);
  if (!ret) {
    g_critical("%s: Error checking owner of service %s: %s", G_STRFUNC, service, error->message);
    g_object_unref(dbus_proxy);
    goto ERROR;
  }
  g_variant_get (ret, "(b)", &dccm_running);
  g_variant_unref (ret);

  g_object_unref(dbus_proxy);
  if (!dccm_running) {
    synce_info("%s is not running, ignoring", dccm_name);
    goto ERROR;
  }

  dev_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
					    G_DBUS_PROXY_FLAGS_NONE,
					    NULL, /* GDBusInterfaceInfo */
					    service,
					    synce_info_get_object_path(info),
					    dev_iface,
					    NULL, /* GCancellable */
					    &error);
  if (dev_proxy == NULL) {
    g_warning("%s: Failed to get proxy for device '%s': %s", G_STRFUNC, synce_info_get_object_path(info), error->message);
    goto ERROR;
  }


  ret = g_dbus_proxy_call_sync (dev_proxy,
				"RequestConnection",
				g_variant_new ("()"),
				G_DBUS_CALL_FLAGS_NONE,
				-1,
				NULL,
				&error);
  if (!ret) {
    synce_warning("%s: Failed to get a connection for %s: %s", G_STRFUNC, synce_info_get_name(info), error->message);
    g_object_unref(dev_proxy);

    /* INVALID_PASSWORD isn't perfect, but seems to be the best we have */
    if (g_error_matches(error, SYNCE_DCCM_ERROR, SYNCE_DCCM_ERROR_DEVICE_LOCKED))
      result = HRESULT_FROM_WIN32(ERROR_INVALID_PASSWORD);

    goto ERROR;
  }
  g_variant_get (ret, "(s)", &unix_path);
  g_variant_unref (ret);

  g_object_unref(dev_proxy);

  fd = get_socket_from_dccm(unix_path);
  g_free(unix_path);

  if (fd < 0)
  {
    synce_warning("%s: Failed to get file-descriptor from %s for %s", G_STRFUNC, dccm_name, synce_info_get_name(info));
    goto ERROR;
  }

  result = S_OK;
  goto OUT;

ERROR:
  if (error != NULL)
    g_error_free(error);

OUT:

  *sockfd = fd;
  return result;
}
Exemple #19
0
static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
		const struct sr_channel_group *cg)
{
	struct dev_context *devc;
	struct sr_channel *ch;
	const char *tmp_str;
	uint64_t samplerate;
	int analog_channel = -1;
	float smallest_diff = INFINITY;
	int idx = -1;
	unsigned i;

	if (!sdi)
		return SR_ERR_ARG;

	devc = sdi->priv;

	/* If a channel group is specified, it must be a valid one. */
	if (cg && !g_slist_find(sdi->channel_groups, cg)) {
		sr_err("Invalid channel group specified.");
		return SR_ERR;
	}

	if (cg) {
		ch = g_slist_nth_data(cg->channels, 0);
		if (!ch)
			return SR_ERR;
		if (ch->type == SR_CHANNEL_ANALOG) {
			if (ch->name[2] < '1' || ch->name[2] > '4')
				return SR_ERR;
			analog_channel = ch->name[2] - '1';
		}
	}

	switch (key) {
	case SR_CONF_NUM_HDIV:
		*data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
		break;
	case SR_CONF_NUM_VDIV:
		*data = g_variant_new_int32(devc->num_vdivs);
		break;
	case SR_CONF_DATA_SOURCE:
		if (devc->data_source == DATA_SOURCE_LIVE)
			*data = g_variant_new_string("Live");
		else if (devc->data_source == DATA_SOURCE_MEMORY)
			*data = g_variant_new_string("Memory");
		else
			*data = g_variant_new_string("Segmented");
		break;
	case SR_CONF_SAMPLERATE:
		if (devc->data_source == DATA_SOURCE_LIVE) {
			samplerate = analog_frame_size(sdi) /
				(devc->timebase * devc->model->series->num_horizontal_divs);
			*data = g_variant_new_uint64(samplerate);
		} else {
			sr_dbg("Unknown data source: %d.", devc->data_source);
			return SR_ERR_NA;
		}
		break;
	case SR_CONF_TRIGGER_SOURCE:
		if (!strcmp(devc->trigger_source, "ACL"))
			tmp_str = "AC Line";
		else if (!strcmp(devc->trigger_source, "CHAN1"))
			tmp_str = "CH1";
		else if (!strcmp(devc->trigger_source, "CHAN2"))
			tmp_str = "CH2";
		else if (!strcmp(devc->trigger_source, "CHAN3"))
			tmp_str = "CH3";
		else if (!strcmp(devc->trigger_source, "CHAN4"))
			tmp_str = "CH4";
		else
			tmp_str = devc->trigger_source;
		*data = g_variant_new_string(tmp_str);
		break;
	case SR_CONF_TRIGGER_SLOPE:
		if (!strncmp(devc->trigger_slope, "POS", 3)) {
			tmp_str = "r";
		} else if (!strncmp(devc->trigger_slope, "NEG", 3)) {
			tmp_str = "f";
		} else {
			sr_dbg("Unknown trigger slope: '%s'.", devc->trigger_slope);
			return SR_ERR_NA;
		}
		*data = g_variant_new_string(tmp_str);
		break;
	case SR_CONF_TRIGGER_LEVEL:
		*data = g_variant_new_double(devc->trigger_level);
		break;
	case SR_CONF_TIMEBASE:
		for (i = 0; i < devc->num_timebases; i++) {
			float tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
			float diff = fabs(devc->timebase - tb);
			if (diff < smallest_diff) {
				smallest_diff = diff;
				idx = i;
			}
		}
		if (idx < 0) {
			sr_dbg("Negative timebase index: %d.", idx);
			return SR_ERR_NA;
		}
		*data = g_variant_new("(tt)", devc->timebases[idx][0],
		                              devc->timebases[idx][1]);
		break;
	case SR_CONF_VDIV:
		if (analog_channel < 0) {
			sr_dbg("Negative analog channel: %d.", analog_channel);
			return SR_ERR_NA;
		}
		for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
			float vdiv = (float)vdivs[i][0] / vdivs[i][1];
			float diff = fabs(devc->vdiv[analog_channel] - vdiv);
			if (diff < smallest_diff) {
				smallest_diff = diff;
				idx = i;
			}
		}
		if (idx < 0) {
			sr_dbg("Negative vdiv index: %d.", idx);
			return SR_ERR_NA;
		}
		*data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
		break;
	case SR_CONF_COUPLING:
		if (analog_channel < 0) {
			sr_dbg("Negative analog channel: %d.", analog_channel);
			return SR_ERR_NA;
		}
		*data = g_variant_new_string(devc->coupling[analog_channel]);
		break;
	case SR_CONF_PROBE_FACTOR:
		if (analog_channel < 0) {
			sr_dbg("Negative analog channel: %d.", analog_channel);
			return SR_ERR_NA;
		}
		*data = g_variant_new_uint64(devc->attenuation[analog_channel]);
		break;
	default:
		return SR_ERR_NA;
	}

	return SR_OK;
}
Exemple #20
0
int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load_data, lua_State *L)
{
  double start_wtime = dt_get_wtime();

#ifndef __WIN32__
  if(getuid() == 0 || geteuid() == 0)
    printf(
        "WARNING: either your user id or the effective user id are 0. are you running darktable as root?\n");
#endif

#if defined(__SSE__)
  // make everything go a lot faster.
  _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
#endif

  dt_set_signal_handlers();

#include "is_supported_platform.h"

  int sse2_supported = 0;

#ifdef HAVE_BUILTIN_CPU_SUPPORTS
  // NOTE: _may_i_use_cpu_feature() looks better, but only avaliable in ICC
  __builtin_cpu_init();
  sse2_supported = __builtin_cpu_supports("sse2");
#else
  sse2_supported = dt_detect_cpu_features() & CPU_FLAG_SSE2;
#endif
  if(!sse2_supported)
  {
    fprintf(stderr, "[dt_init] SSE2 instruction set is unavailable.\n");
    fprintf(stderr, "[dt_init] expect a LOT of functionality to be broken. you have been warned.\n");
  }

#ifdef M_MMAP_THRESHOLD
  mallopt(M_MMAP_THRESHOLD, 128 * 1024); /* use mmap() for large allocations */
#endif

  // make sure that stack/frame limits are good (musl)
  dt_set_rlimits();

  // we have to have our share dir in XDG_DATA_DIRS,
  // otherwise GTK+ won't find our logo for the about screen (and maybe other things)
  {
    const gchar *xdg_data_dirs = g_getenv("XDG_DATA_DIRS");
    gchar *new_xdg_data_dirs = NULL;
    gboolean set_env = TRUE;
    if(xdg_data_dirs != NULL && *xdg_data_dirs != '\0')
    {
      // check if DARKTABLE_SHAREDIR is already in there
      gboolean found = FALSE;
      gchar **tokens = g_strsplit(xdg_data_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
      // xdg_data_dirs is neither NULL nor empty => tokens != NULL
      for(char **iter = tokens; *iter != NULL; iter++)
        if(!strcmp(DARKTABLE_SHAREDIR, *iter))
        {
          found = TRUE;
          break;
        }
      g_strfreev(tokens);
      if(found)
        set_env = FALSE;
      else
        new_xdg_data_dirs = g_strjoin(G_SEARCHPATH_SEPARATOR_S, DARKTABLE_SHAREDIR, xdg_data_dirs, NULL);
    }
    else
    {
#ifndef _WIN32
      // see http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html for a reason to use those as a
      // default
      if(!g_strcmp0(DARKTABLE_SHAREDIR, "/usr/local/share")
         || !g_strcmp0(DARKTABLE_SHAREDIR, "/usr/local/share/")
         || !g_strcmp0(DARKTABLE_SHAREDIR, "/usr/share") || !g_strcmp0(DARKTABLE_SHAREDIR, "/usr/share/"))
        new_xdg_data_dirs = g_strdup("/usr/local/share/" G_SEARCHPATH_SEPARATOR_S "/usr/share/");
      else
        new_xdg_data_dirs = g_strdup_printf("%s" G_SEARCHPATH_SEPARATOR_S "/usr/local/share/" G_SEARCHPATH_SEPARATOR_S
                                            "/usr/share/", DARKTABLE_SHAREDIR);
#else
      set_env = FALSE;
#endif
    }

    if(set_env) g_setenv("XDG_DATA_DIRS", new_xdg_data_dirs, 1);
    g_free(new_xdg_data_dirs);
  }

  setlocale(LC_ALL, "");
  bindtextdomain(GETTEXT_PACKAGE, DARKTABLE_LOCALEDIR);
  bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
  textdomain(GETTEXT_PACKAGE);

  // init all pointers to 0:
  memset(&darktable, 0, sizeof(darktable_t));

  darktable.start_wtime = start_wtime;

  darktable.progname = argv[0];

  // FIXME: move there into dt_database_t
  dt_pthread_mutex_init(&(darktable.db_insert), NULL);
  dt_pthread_mutex_init(&(darktable.plugin_threadsafe), NULL);
  dt_pthread_mutex_init(&(darktable.capabilities_threadsafe), NULL);
  darktable.control = (dt_control_t *)calloc(1, sizeof(dt_control_t));

  // database
  char *dbfilename_from_command = NULL;
  char *noiseprofiles_from_command = NULL;
  char *datadir_from_command = NULL;
  char *moduledir_from_command = NULL;
  char *tmpdir_from_command = NULL;
  char *configdir_from_command = NULL;
  char *cachedir_from_command = NULL;

#ifdef HAVE_OPENCL
  gboolean exclude_opencl = FALSE;
  gboolean print_statistics = strcmp(argv[0], "darktable-cltest");
#endif

#ifdef USE_LUA
  char *lua_command = NULL;
#endif

  darktable.num_openmp_threads = 1;
#ifdef _OPENMP
  darktable.num_openmp_threads = omp_get_num_procs();
#endif
  darktable.unmuted = 0;
  GSList *config_override = NULL;
  for(int k = 1; k < argc; k++)
  {
    if(argv[k][0] == '-')
    {
      if(!strcmp(argv[k], "--help"))
      {
        return usage(argv[0]);
      }
      if(!strcmp(argv[k], "-h"))
      {
        return usage(argv[0]);
      }
      else if(!strcmp(argv[k], "--version"))
      {
#ifdef USE_LUA
        const char *lua_api_version = strcmp(LUA_API_VERSION_SUFFIX, "") ?
                                      STR(LUA_API_VERSION_MAJOR) "."
                                      STR(LUA_API_VERSION_MINOR) "."
                                      STR(LUA_API_VERSION_PATCH) "-"
                                      LUA_API_VERSION_SUFFIX :
                                      STR(LUA_API_VERSION_MAJOR) "."
                                      STR(LUA_API_VERSION_MINOR) "."
                                      STR(LUA_API_VERSION_PATCH);
#endif
        printf("this is %s\ncopyright (c) 2009-%s johannes hanika\n" PACKAGE_BUGREPORT "\n\ncompile options:\n"
               "  bit depth is %s\n"
#ifdef _DEBUG
               "  debug build\n"
#else
               "  normal build\n"
#endif
#if defined(__SSE2__) && defined(__SSE__)
               "  SSE2 optimized codepath enabled\n"
#else
               "  SSE2 optimized codepath disabled\n"
#endif
#ifdef _OPENMP
               "  OpenMP support enabled\n"
#else
               "  OpenMP support disabled\n"
#endif

#ifdef HAVE_OPENCL
               "  OpenCL support enabled\n"
#else
               "  OpenCL support disabled\n"
#endif

#ifdef USE_LUA
               "  Lua support enabled, API version %s\n"
#else
               "  Lua support disabled\n"
#endif

#ifdef USE_COLORDGTK
               "  Colord support enabled\n"
#else
               "  Colord support disabled\n"
#endif

#ifdef HAVE_GPHOTO2
               "  gPhoto2 support enabled\n"
#else
               "  gPhoto2 support disabled\n"
#endif

#ifdef HAVE_GRAPHICSMAGICK
               "  GraphicsMagick support enabled\n"
#else
               "  GraphicsMagick support disabled\n"
#endif

#ifdef HAVE_OPENEXR
               "  OpenEXR support enabled\n"
#else
               "  OpenEXR support disabled\n"
#endif
               ,
               darktable_package_string,
               darktable_last_commit_year,
               (sizeof(void *) == 8 ? "64 bit" : sizeof(void *) == 4 ? "32 bit" : "unknown")
#if USE_LUA
                   ,
               lua_api_version
#endif
               );
        return 1;
      }
      else if(!strcmp(argv[k], "--library") && argc > k + 1)
      {
        dbfilename_from_command = argv[++k];
        argv[k-1] = NULL;
        argv[k] = NULL;
      }
      else if(!strcmp(argv[k], "--datadir") && argc > k + 1)
      {
        datadir_from_command = argv[++k];
        argv[k-1] = NULL;
        argv[k] = NULL;
      }
      else if(!strcmp(argv[k], "--moduledir") && argc > k + 1)
      {
        moduledir_from_command = argv[++k];
        argv[k-1] = NULL;
        argv[k] = NULL;
      }
      else if(!strcmp(argv[k], "--tmpdir") && argc > k + 1)
      {
        tmpdir_from_command = argv[++k];
        argv[k-1] = NULL;
        argv[k] = NULL;
      }
      else if(!strcmp(argv[k], "--configdir") && argc > k + 1)
      {
        configdir_from_command = argv[++k];
        argv[k-1] = NULL;
        argv[k] = NULL;
      }
      else if(!strcmp(argv[k], "--cachedir") && argc > k + 1)
      {
        cachedir_from_command = argv[++k];
        argv[k-1] = NULL;
        argv[k] = NULL;
      }
      else if(!strcmp(argv[k], "--localedir") && argc > k + 1)
      {
        bindtextdomain(GETTEXT_PACKAGE, argv[++k]);
        argv[k-1] = NULL;
        argv[k] = NULL;
      }
      else if(argv[k][1] == 'd' && argc > k + 1)
      {
        if(!strcmp(argv[k + 1], "all"))
          darktable.unmuted = 0xffffffff; // enable all debug information
        else if(!strcmp(argv[k + 1], "cache"))
          darktable.unmuted |= DT_DEBUG_CACHE; // enable debugging for lib/film/cache module
        else if(!strcmp(argv[k + 1], "control"))
          darktable.unmuted |= DT_DEBUG_CONTROL; // enable debugging for scheduler module
        else if(!strcmp(argv[k + 1], "dev"))
          darktable.unmuted |= DT_DEBUG_DEV; // develop module
        else if(!strcmp(argv[k + 1], "input"))
          darktable.unmuted |= DT_DEBUG_INPUT; // input devices
        else if(!strcmp(argv[k + 1], "camctl"))
          darktable.unmuted |= DT_DEBUG_CAMCTL; // camera control module
        else if(!strcmp(argv[k + 1], "perf"))
          darktable.unmuted |= DT_DEBUG_PERF; // performance measurements
        else if(!strcmp(argv[k + 1], "pwstorage"))
          darktable.unmuted |= DT_DEBUG_PWSTORAGE; // pwstorage module
        else if(!strcmp(argv[k + 1], "opencl"))
          darktable.unmuted |= DT_DEBUG_OPENCL; // gpu accel via opencl
        else if(!strcmp(argv[k + 1], "sql"))
          darktable.unmuted |= DT_DEBUG_SQL; // SQLite3 queries
        else if(!strcmp(argv[k + 1], "memory"))
          darktable.unmuted |= DT_DEBUG_MEMORY; // some stats on mem usage now and then.
        else if(!strcmp(argv[k + 1], "lighttable"))
          darktable.unmuted |= DT_DEBUG_LIGHTTABLE; // lighttable related stuff.
        else if(!strcmp(argv[k + 1], "nan"))
          darktable.unmuted |= DT_DEBUG_NAN; // check for NANs when processing the pipe.
        else if(!strcmp(argv[k + 1], "masks"))
          darktable.unmuted |= DT_DEBUG_MASKS; // masks related stuff.
        else if(!strcmp(argv[k + 1], "lua"))
          darktable.unmuted |= DT_DEBUG_LUA; // lua errors are reported on console
        else if(!strcmp(argv[k + 1], "print"))
          darktable.unmuted |= DT_DEBUG_PRINT; // print errors are reported on console
        else if(!strcmp(argv[k + 1], "camsupport"))
          darktable.unmuted |= DT_DEBUG_CAMERA_SUPPORT; // camera support warnings are reported on console
        else
          return usage(argv[0]);
        k++;
        argv[k-1] = NULL;
        argv[k] = NULL;
      }
      else if(argv[k][1] == 't' && argc > k + 1)
      {
        darktable.num_openmp_threads = CLAMP(atol(argv[k + 1]), 1, 100);
        printf("[dt_init] using %d threads for openmp parallel sections\n", darktable.num_openmp_threads);
        k++;
        argv[k-1] = NULL;
        argv[k] = NULL;
      }
      else if(!strcmp(argv[k], "--conf") && argc > k + 1)
      {
        gchar *keyval = g_strdup(argv[++k]), *c = keyval;
        argv[k-1] = NULL;
        argv[k] = NULL;
        gchar *end = keyval + strlen(keyval);
        while(*c != '=' && c < end) c++;
        if(*c == '=' && *(c + 1) != '\0')
        {
          *c++ = '\0';
          dt_conf_string_entry_t *entry = (dt_conf_string_entry_t *)g_malloc(sizeof(dt_conf_string_entry_t));
          entry->key = g_strdup(keyval);
          entry->value = g_strdup(c);
          config_override = g_slist_append(config_override, entry);
        }
        g_free(keyval);
      }
      else if(!strcmp(argv[k], "--noiseprofiles") && argc > k + 1)
      {
        noiseprofiles_from_command = argv[++k];
        argv[k-1] = NULL;
        argv[k] = NULL;
      }
      else if(!strcmp(argv[k], "--luacmd") && argc > k + 1)
      {
#ifdef USE_LUA
        lua_command = argv[++k];
#else
        ++k;
#endif
        argv[k-1] = NULL;
        argv[k] = NULL;
      }
      else if(!strcmp(argv[k], "--disable-opencl"))
      {
#ifdef HAVE_OPENCL
        exclude_opencl = TRUE;
#endif
        argv[k] = NULL;
      }
      else if(!strcmp(argv[k], "--"))
      {
        // "--" confuses the argument parser of glib/gtk. remove it.
        argv[k] = NULL;
        break;
      }
      else
        return usage(argv[0]); // fail on unrecognized options
    }
  }

  // remove the NULLs to not confuse gtk_init() later.
  for(int i = 1; i < argc; i++)
  {
    int k;
    for(k = i; k < argc; k++)
      if(argv[k] != NULL) break;

    if(k > i)
    {
      k -= i;
      for(int j = i + k; j < argc; j++)
      {
        argv[j-k] = argv[j];
        argv[j] = NULL;
      }
      argc -= k;
    }
  }

  if(darktable.unmuted & DT_DEBUG_MEMORY)
  {
    fprintf(stderr, "[memory] at startup\n");
    dt_print_mem_usage();
  }

  if(init_gui)
  {
    // I doubt that connecting to dbus for darktable-cli makes sense
    darktable.dbus = dt_dbus_init();

    // make sure that we have no stale global progress bar visible. thus it's run as early is possible
    dt_control_progress_init(darktable.control);
  }

#ifdef _OPENMP
  omp_set_num_threads(darktable.num_openmp_threads);
#endif
  dt_loc_init_datadir(datadir_from_command);
  dt_loc_init_plugindir(moduledir_from_command);
  if(dt_loc_init_tmp_dir(tmpdir_from_command))
  {
    fprintf(stderr, "error: invalid temporary directory: %s\n", darktable.tmpdir);
    return usage(argv[0]);
  }
  dt_loc_init_user_config_dir(configdir_from_command);
  dt_loc_init_user_cache_dir(cachedir_from_command);

#ifdef USE_LUA
  dt_lua_init_early(L);
#endif

  // thread-safe init:
  dt_exif_init();
  char datadir[PATH_MAX] = { 0 };
  dt_loc_get_user_config_dir(datadir, sizeof(datadir));
  char darktablerc[PATH_MAX] = { 0 };
  snprintf(darktablerc, sizeof(darktablerc), "%s/darktablerc", datadir);

  // initialize the config backend. this needs to be done first...
  darktable.conf = (dt_conf_t *)calloc(1, sizeof(dt_conf_t));
  dt_conf_init(darktable.conf, darktablerc, config_override);
  g_slist_free_full(config_override, g_free);

  // set the interface language
  const gchar *lang = dt_conf_get_string("ui_last/gui_language");
#if defined(_WIN32)
  // get the default locale if no language preference was specified in the config file
  if(lang == NULL || lang[0] == '\0')
  {
    const wchar_t *wcLocaleName = NULL;
    wcLocaleName = dtwin_get_locale();
    if(wcLocaleName != NULL)
    {
      gchar *langLocale;
      langLocale = g_utf16_to_utf8(wcLocaleName, -1, NULL, NULL, NULL);
      if(langLocale != NULL)
      {
        g_free((gchar *)lang);
        lang = g_strdup(langLocale);
      }
    }
  }
#endif // defined (_WIN32)

  if(lang != NULL && lang[0] != '\0')
  {
    g_setenv("LANGUAGE", lang, 1);
    if(setlocale(LC_ALL, lang) != NULL) gtk_disable_setlocale();
    setlocale(LC_MESSAGES, lang);
    g_setenv("LANG", lang, 1);
  }
  g_free((gchar *)lang);

  // we need this REALLY early so that error messages can be shown, however after gtk_disable_setlocale
  if(init_gui)
  {
#ifdef GDK_WINDOWING_WAYLAND
    // There are currently bad interactions with Wayland (drop-downs
    // are very narrow, scroll events lost). Until this is fixed, give
    // priority to the XWayland backend for Wayland users.
    gdk_set_allowed_backends("x11,*");
#endif
    gtk_init(&argc, &argv);
  }

  // detect cpu features and decide which codepaths to enable
  dt_codepaths_init();

  // get the list of color profiles
  darktable.color_profiles = dt_colorspaces_init();

  // initialize the database
  darktable.db = dt_database_init(dbfilename_from_command, load_data);
  if(darktable.db == NULL)
  {
    printf("ERROR : cannot open database\n");
    return 1;
  }
  else if(!dt_database_get_lock_acquired(darktable.db))
  {
    gboolean image_loaded_elsewhere = FALSE;
#ifndef MAC_INTEGRATION
    // send the images to the other instance via dbus
    fprintf(stderr, "trying to open the images in the running instance\n");

    GDBusConnection *connection = NULL;
    for(int i = 1; i < argc; i++)
    {
      // make the filename absolute ...
      if(argv[i] == NULL || *argv[i] == '\0') continue;
      gchar *filename = dt_util_normalize_path(argv[i]);
      if(filename == NULL) continue;
      if(!connection) connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
      // ... and send it to the running instance of darktable
      image_loaded_elsewhere = g_dbus_connection_call_sync(connection, "org.darktable.service", "/darktable",
                                                           "org.darktable.service.Remote", "Open",
                                                           g_variant_new("(s)", filename), NULL,
                                                           G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL) != NULL;
      g_free(filename);
    }
    if(connection) g_object_unref(connection);
#endif

    if(!image_loaded_elsewhere) dt_database_show_error(darktable.db);

    return 1;
  }

  // Initialize the signal system
  darktable.signals = dt_control_signal_init();

  // Make sure that the database and xmp files are in sync
  // We need conf and db to be up and running for that which is the case here.
  // FIXME: is this also useful in non-gui mode?
  GList *changed_xmp_files = NULL;
  if(init_gui && dt_conf_get_bool("run_crawler_on_start"))
  {
    changed_xmp_files = dt_control_crawler_run();
  }

  if(init_gui)
  {
    dt_control_init(darktable.control);
  }
  else
  {
    if(dbfilename_from_command && !strcmp(dbfilename_from_command, ":memory:"))
      dt_gui_presets_init(); // init preset db schema.
    darktable.control->running = 0;
    darktable.control->accelerators = NULL;
    dt_pthread_mutex_init(&darktable.control->run_mutex, NULL);
  }

  // initialize collection query
  darktable.collection = dt_collection_new(NULL);

  /* initialize selection */
  darktable.selection = dt_selection_new();

  /* capabilities set to NULL */
  darktable.capabilities = NULL;

  // Initialize the password storage engine
  darktable.pwstorage = dt_pwstorage_new();

  darktable.guides = dt_guides_init();

#ifdef HAVE_GRAPHICSMAGICK
  /* GraphicsMagick init */
  InitializeMagick(darktable.progname);

  // *SIGH*
  dt_set_signal_handlers();
#endif

  darktable.opencl = (dt_opencl_t *)calloc(1, sizeof(dt_opencl_t));
#ifdef HAVE_OPENCL
  dt_opencl_init(darktable.opencl, exclude_opencl, print_statistics);
#endif

  darktable.points = (dt_points_t *)calloc(1, sizeof(dt_points_t));
  dt_points_init(darktable.points, dt_get_num_threads());

  darktable.noiseprofile_parser = dt_noiseprofile_init(noiseprofiles_from_command);

  // must come before mipmap_cache, because that one will need to access
  // image dimensions stored in here:
  darktable.image_cache = (dt_image_cache_t *)calloc(1, sizeof(dt_image_cache_t));
  dt_image_cache_init(darktable.image_cache);

  darktable.mipmap_cache = (dt_mipmap_cache_t *)calloc(1, sizeof(dt_mipmap_cache_t));
  dt_mipmap_cache_init(darktable.mipmap_cache);

  // The GUI must be initialized before the views, because the init()
  // functions of the views depend on darktable.control->accels_* to register
  // their keyboard accelerators

  if(init_gui)
  {
    darktable.gui = (dt_gui_gtk_t *)calloc(1, sizeof(dt_gui_gtk_t));
    if(dt_gui_gtk_init(darktable.gui)) return 1;
    dt_bauhaus_init();
  }
  else
    darktable.gui = NULL;

  darktable.view_manager = (dt_view_manager_t *)calloc(1, sizeof(dt_view_manager_t));
  dt_view_manager_init(darktable.view_manager);

  // check whether we were able to load darkroom view. if we failed, we'll crash everywhere later on.
  if(!darktable.develop) return 1;

  darktable.imageio = (dt_imageio_t *)calloc(1, sizeof(dt_imageio_t));
  dt_imageio_init(darktable.imageio);

  // load the darkroom mode plugins once:
  dt_iop_load_modules_so();

  if(init_gui)
  {
#ifdef HAVE_GPHOTO2
    // Initialize the camera control.
    // this is done late so that the gui can react to the signal sent but before switching to lighttable!
    darktable.camctl = dt_camctl_new();
#endif

    darktable.lib = (dt_lib_t *)calloc(1, sizeof(dt_lib_t));
    dt_lib_init(darktable.lib);

    dt_gui_gtk_load_config();

    // init the gui part of views
    dt_view_manager_gui_init(darktable.view_manager);
    // Loading the keybindings
    char keyfile[PATH_MAX] = { 0 };

    // First dump the default keymapping
    snprintf(keyfile, sizeof(keyfile), "%s/keyboardrc_default", datadir);
    gtk_accel_map_save(keyfile);

    // Removing extraneous semi-colons from the default keymap
    strip_semicolons_from_keymap(keyfile);

    // Then load any modified keys if available
    snprintf(keyfile, sizeof(keyfile), "%s/keyboardrc", datadir);
    if(g_file_test(keyfile, G_FILE_TEST_EXISTS))
      gtk_accel_map_load(keyfile);
    else
      gtk_accel_map_save(keyfile); // Save the default keymap if none is present

    // initialize undo struct
    darktable.undo = dt_undo_init();
  }

  if(darktable.unmuted & DT_DEBUG_MEMORY)
  {
    fprintf(stderr, "[memory] after successful startup\n");
    dt_print_mem_usage();
  }

  dt_image_local_copy_synch();

/* init lua last, since it's user made stuff it must be in the real environment */
#ifdef USE_LUA
  dt_lua_init(darktable.lua_state.state, lua_command);
#endif

  if(init_gui)
  {
    const char *mode = "lighttable";
    // april 1st: you have to earn using dt first! or know that you can switch views with keyboard shortcuts
    time_t now;
    time(&now);
    struct tm lt;
    localtime_r(&now, &lt);
    if(lt.tm_mon == 3 && lt.tm_mday == 1) mode = "knight";
    // we have to call dt_ctl_switch_mode_to() here already to not run into a lua deadlock.
    // having another call later is ok
    dt_ctl_switch_mode_to(mode);

#ifndef MAC_INTEGRATION
    // load image(s) specified on cmdline.
    // this has to happen after lua is initialized as image import can run lua code
    // If only one image is listed, attempt to load it in darkroom
    int last_id = 0;
    gboolean only_single_images = TRUE;
    int loaded_images = 0;

    for(int i = 1; i < argc; i++)
    {
      gboolean single_image = FALSE;
      if(argv[i] == NULL || *argv[i] == '\0') continue;
      int new_id = dt_load_from_string(argv[i], FALSE, &single_image);
      if(new_id > 0)
      {
        last_id = new_id;
        loaded_images++;
        if(!single_image) only_single_images = FALSE;
      }
    }

    if(loaded_images == 1 && only_single_images)
    {
      dt_control_set_mouse_over_id(last_id);
      dt_ctl_switch_mode_to("darkroom");
    }
#endif
  }

  // last but not least construct the popup that asks the user about images whose xmp files are newer than the
  // db entry
  if(init_gui && changed_xmp_files)
  {
    dt_control_crawler_show_image_list(changed_xmp_files);
  }

  dt_print(DT_DEBUG_CONTROL, "[init] startup took %f seconds\n", dt_get_wtime() - start_wtime);

  return 0;
}
static void
enroll_fingerprints (GtkWindow *parent,
                     GtkWidget *label1,
                     GtkWidget *label2,
                     UmUser    *user)
{
        GDBusProxy *device;
        GtkBuilder *dialog;
        EnrollData *data;
        GtkWidget *ass;
        const char *filename;
        char *msg;
        GVariant *result;
        GError *error = NULL;

        device = NULL;

        if (manager == NULL) {
                create_manager ();
                if (manager != NULL)
                        device = get_first_device ();
        } else {
                device = get_first_device ();
        }

        if (manager == NULL || device == NULL) {
                GtkWidget *d;

                d = get_error_dialog (_("Could not access any fingerprint readers"),
                                      _("Please contact your system administrator for help."),
                                      parent);
                gtk_dialog_run (GTK_DIALOG (d));
                gtk_widget_destroy (d);
                return;
        }

        data = g_new0 (EnrollData, 1);
        data->device = device;
        data->label1 = label1;
        data->label2 = label2;

        /* Get some details about the device */
        result = g_dbus_connection_call_sync (connection,
                                              "net.reactivated.Fprint",
                                              g_dbus_proxy_get_object_path (data->device),
                                              "org.freedesktop.DBus.Properties",
                                              "GetAll",
                                              g_variant_new ("(s)", "net.reactivated.Fprint.Device"),
                                              G_VARIANT_TYPE ("(a{sv})"),
                                              G_DBUS_CALL_FLAGS_NONE,
                                              -1,
                                              NULL,
                                              NULL);
        if (result) {
                GVariant *props;
                gchar *scan_type;

                g_variant_get (result, "(@a{sv})", &props);
                g_variant_lookup (props, "name", "s", &data->name);
                g_variant_lookup (props, "scan-type", "s", &scan_type);
                if (g_strcmp0 (scan_type, "swipe") == 0)
                        data->is_swipe = TRUE;
                g_free (scan_type);
                g_variant_unref (props);
                g_variant_unref (result);
        }

        dialog = gtk_builder_new ();
        gtk_builder_set_translation_domain (dialog, GETTEXT_PACKAGE);
        filename = UIDIR "/account-fingerprint.ui";
        if (!g_file_test (filename, G_FILE_TEST_EXISTS))
                filename = "data/account-fingerprint.ui";
        if (!gtk_builder_add_from_file (dialog, filename, &error)) {
                g_error ("%s", error->message);
                g_error_free (error);
                return;
        }
        data->dialog = dialog;

        ass = WID ("assistant");
        gtk_window_set_title (GTK_WINDOW (ass), _("Enable Fingerprint Login"));
        gtk_window_set_transient_for (GTK_WINDOW (ass), parent);
        gtk_window_set_modal (GTK_WINDOW (ass), TRUE);
        gtk_window_set_resizable (GTK_WINDOW (ass), FALSE);
        gtk_window_set_type_hint (GTK_WINDOW (ass), GDK_WINDOW_TYPE_HINT_DIALOG);

        g_signal_connect (G_OBJECT (ass), "cancel",
                          G_CALLBACK (assistant_cancelled), data);
        g_signal_connect (G_OBJECT (ass), "close",
                          G_CALLBACK (assistant_cancelled), data);
        g_signal_connect (G_OBJECT (ass), "prepare",
                          G_CALLBACK (assistant_prepare), data);

        /* Page 1 */
        gtk_combo_box_set_active (GTK_COMBO_BOX (WID ("finger_combobox")), 0);

        g_signal_connect (G_OBJECT (WID ("radiobutton1")), "toggled",
                          G_CALLBACK (finger_radio_button_toggled), data);
        g_signal_connect (G_OBJECT (WID ("radiobutton2")), "toggled",
                          G_CALLBACK (finger_radio_button_toggled), data);
        g_signal_connect (G_OBJECT (WID ("radiobutton3")), "toggled",
                          G_CALLBACK (finger_radio_button_toggled), data);
        g_signal_connect (G_OBJECT (WID ("finger_combobox")), "changed",
                          G_CALLBACK (finger_combobox_changed), data);

        data->finger = selected_finger (dialog);

        g_object_set_data (G_OBJECT (WID("page1")), "name", "intro");

        /* translators:
         * The variable is the name of the device, for example:
         * "To enable fingerprint login, you need to save one of your fingerprints, using the
         * 'Digital Persona U.are.U 4000/4000B' device."
         */
        msg = g_strdup_printf (_("To enable fingerprint login, you need to save one of your fingerprints, using the '%s' device."),
                               data->name);
        gtk_label_set_text (GTK_LABEL (WID("intro-label")), msg);
        g_free (msg);

        gtk_assistant_set_page_complete (GTK_ASSISTANT (ass), WID("page1"), TRUE);

        gtk_assistant_set_page_title (GTK_ASSISTANT (ass), WID("page1"), _("Selecting finger"));
        gtk_assistant_set_page_title (GTK_ASSISTANT (ass), WID("page2"), _("Enrolling fingerprints"));
        gtk_assistant_set_page_title (GTK_ASSISTANT (ass), WID("page3"), _("Summary"));

        /* Page 2 */
        g_object_set_data (G_OBJECT (WID("page2")), "name", "enroll");

        msg = g_strdup_printf (TR(finger_str_to_msg (data->finger, data->is_swipe)), data->name);
        gtk_label_set_text (GTK_LABEL (WID("enroll-label")), msg);
        g_free (msg);

        /* Page 3 */
        g_object_set_data (G_OBJECT (WID("page3")), "name", "summary");

        data->ass = ass;
        gtk_widget_show_all (ass);
}
Exemple #22
0
int dt_init(int argc, char *argv[], const int init_gui)
{
#ifndef __WIN32__
  if(getuid() == 0 || geteuid() == 0)
    printf("WARNING: either your user id or the effective user id are 0. are you running darktable as root?\n");
#endif

  // make everything go a lot faster.
  _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
#if !defined __APPLE__ && !defined __WIN32__
  _dt_sigsegv_old_handler = signal(SIGSEGV,&_dt_sigsegv_handler);
#endif

#ifndef __GNUC_PREREQ
  // on OSX, gcc-4.6 and clang chokes if this is not here.
  #if defined __GNUC__ && defined __GNUC_MINOR__
  # define __GNUC_PREREQ(maj, min) \
  ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
  #else
  # define __GNUC_PREREQ(maj, min) 0
  #endif
#endif
#ifndef __has_builtin
// http://clang.llvm.org/docs/LanguageExtensions.html#feature-checking-macros
  #define __has_builtin(x) false
#endif

#ifndef __SSE3__
  #error "Unfortunately we depend on SSE3 instructions at this time."
  #error "Please contribute a backport patch (or buy a newer processor)."
#else
  #if (__GNUC_PREREQ(4,8) || __has_builtin(__builtin_cpu_supports))
  //FIXME: check will work only in GCC 4.8+ !!! implement manual cpuid check !!!
  //NOTE: _may_i_use_cpu_feature() looks better, but only avaliable in ICC
  if (!__builtin_cpu_supports("sse3"))
  {
    fprintf(stderr, "[dt_init] unfortunately we depend on SSE3 instructions at this time.\n");
    fprintf(stderr, "[dt_init] please contribute a backport patch (or buy a newer processor).\n");
    return 1;
  }
  #else
  //FIXME: no way to check for SSE3 in runtime, implement manual cpuid check !!!
  #endif
#endif

#ifdef M_MMAP_THRESHOLD
  mallopt(M_MMAP_THRESHOLD,128*1024) ; /* use mmap() for large allocations */
#endif

  // we have to have our share dir in XDG_DATA_DIRS,
  // otherwise GTK+ won't find our logo for the about screen (and maybe other things)
  {
    const gchar *xdg_data_dirs = g_getenv("XDG_DATA_DIRS");
    gchar *new_xdg_data_dirs = NULL;
    gboolean set_env = TRUE;
    if(xdg_data_dirs != NULL && *xdg_data_dirs != '\0')
    {
      // check if DARKTABLE_SHAREDIR is already in there
      gboolean found = FALSE;
      gchar **tokens = g_strsplit(xdg_data_dirs, ":", 0);
      // xdg_data_dirs is neither NULL nor empty => tokens != NULL
      for(char **iter = tokens; *iter != NULL; iter++)
        if(!strcmp(DARKTABLE_SHAREDIR, *iter))
        {
          found = TRUE;
          break;
        }
      g_strfreev(tokens);
      if(found)
        set_env = FALSE;
      else
        new_xdg_data_dirs = g_strjoin(":", DARKTABLE_SHAREDIR, xdg_data_dirs, NULL);
    }
    else
      new_xdg_data_dirs = g_strdup(DARKTABLE_SHAREDIR);

    if(set_env)
      g_setenv("XDG_DATA_DIRS", new_xdg_data_dirs, 1);
    g_free(new_xdg_data_dirs);
  }

  setlocale(LC_ALL, "");
  bindtextdomain (GETTEXT_PACKAGE, DARKTABLE_LOCALEDIR);
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
  textdomain (GETTEXT_PACKAGE);


  // init all pointers to 0:
  memset(&darktable, 0, sizeof(darktable_t));

  darktable.progname = argv[0];

  // database
  gchar *dbfilename_from_command = NULL;
  char *datadir_from_command = NULL;
  char *moduledir_from_command = NULL;
  char *tmpdir_from_command = NULL;
  char *configdir_from_command = NULL;
  char *cachedir_from_command = NULL;

  darktable.num_openmp_threads = 1;
#ifdef _OPENMP
  darktable.num_openmp_threads = omp_get_num_procs();
#endif
  darktable.unmuted = 0;
  GSList *images_to_load = NULL, *config_override = NULL;
  for(int k=1; k<argc; k++)
  {
    if(argv[k][0] == '-')
    {
      if(!strcmp(argv[k], "--help"))
      {
        return usage(argv[0]);
      }
      if(!strcmp(argv[k], "-h"))
      {
        return usage(argv[0]);
      }
      else if(!strcmp(argv[k], "--version"))
      {
        printf("this is "PACKAGE_STRING"\ncopyright (c) 2009-2014 johannes hanika\n"PACKAGE_BUGREPORT"\n"
#ifdef _OPENMP
        "OpenMP support enabled\n"
#else
        "OpenMP support disabled\n"
#endif
        );
        return 1;
      }
      else if(!strcmp(argv[k], "--library"))
      {
        dbfilename_from_command = argv[++k];
      }
      else if(!strcmp(argv[k], "--datadir"))
      {
        datadir_from_command = argv[++k];
      }
      else if(!strcmp(argv[k], "--moduledir"))
      {
        moduledir_from_command = argv[++k];
      }
      else if(!strcmp(argv[k], "--tmpdir"))
      {
        tmpdir_from_command = argv[++k];
      }
      else if(!strcmp(argv[k], "--configdir"))
      {
        configdir_from_command = argv[++k];
      }
      else if(!strcmp(argv[k], "--cachedir"))
      {
        cachedir_from_command = argv[++k];
      }
      else if(!strcmp(argv[k], "--localedir"))
      {
        bindtextdomain (GETTEXT_PACKAGE, argv[++k]);
      }
      else if(argv[k][1] == 'd' && argc > k+1)
      {
        if(!strcmp(argv[k+1], "all"))             darktable.unmuted = 0xffffffff;   // enable all debug information
        else if(!strcmp(argv[k+1], "cache"))      darktable.unmuted |= DT_DEBUG_CACHE;   // enable debugging for lib/film/cache module
        else if(!strcmp(argv[k+1], "control"))    darktable.unmuted |= DT_DEBUG_CONTROL; // enable debugging for scheduler module
        else if(!strcmp(argv[k+1], "dev"))        darktable.unmuted |= DT_DEBUG_DEV; // develop module
        else if(!strcmp(argv[k+1], "fswatch"))    darktable.unmuted |= DT_DEBUG_FSWATCH; // fswatch module
        else if(!strcmp(argv[k+1], "input"))      darktable.unmuted |= DT_DEBUG_INPUT; // input devices
        else if(!strcmp(argv[k+1], "camctl"))     darktable.unmuted |= DT_DEBUG_CAMCTL; // camera control module
        else if(!strcmp(argv[k+1], "perf"))       darktable.unmuted |= DT_DEBUG_PERF; // performance measurements
        else if(!strcmp(argv[k+1], "pwstorage"))  darktable.unmuted |= DT_DEBUG_PWSTORAGE; // pwstorage module
        else if(!strcmp(argv[k+1], "opencl"))     darktable.unmuted |= DT_DEBUG_OPENCL;    // gpu accel via opencl
        else if(!strcmp(argv[k+1], "sql"))        darktable.unmuted |= DT_DEBUG_SQL; // SQLite3 queries
        else if(!strcmp(argv[k+1], "memory"))     darktable.unmuted |= DT_DEBUG_MEMORY; // some stats on mem usage now and then.
        else if(!strcmp(argv[k+1], "lighttable")) darktable.unmuted |= DT_DEBUG_LIGHTTABLE; // lighttable related stuff.
        else if(!strcmp(argv[k+1], "nan"))        darktable.unmuted |= DT_DEBUG_NAN; // check for NANs when processing the pipe.
        else if(!strcmp(argv[k+1], "masks"))      darktable.unmuted |= DT_DEBUG_MASKS; // masks related stuff.
        else if(!strcmp(argv[k+1], "lua"))        darktable.unmuted |= DT_DEBUG_LUA; // lua errors are reported on console
        else return usage(argv[0]);
        k ++;
      }
      else if(argv[k][1] == 't' && argc > k+1)
      {
        darktable.num_openmp_threads = CLAMP(atol(argv[k+1]), 1, 100);
        printf("[dt_init] using %d threads for openmp parallel sections\n", darktable.num_openmp_threads);
        k ++;
      }
      else if(!strcmp(argv[k], "--conf"))
      {
        gchar *keyval = g_strdup(argv[++k]), *c = keyval;
        while(*c != '=' && c < keyval + strlen(keyval)) c++;
        if(*c == '=' && *(c+1) != '\0')
        {
          *c++ = '\0';
          dt_conf_string_entry_t *entry = (dt_conf_string_entry_t*)g_malloc(sizeof(dt_conf_string_entry_t));
          entry->key = g_strdup(keyval);
          entry->value = g_strdup(c);
          config_override = g_slist_append(config_override, entry);
        }
        g_free(keyval);
      }
    }
#ifndef MAC_INTEGRATION
    else
    {
      images_to_load = g_slist_append(images_to_load, argv[k]);
    }
#endif
  }

  if(darktable.unmuted & DT_DEBUG_MEMORY)
  {
    fprintf(stderr, "[memory] at startup\n");
    dt_print_mem_usage();
  }

#ifdef _OPENMP
  omp_set_num_threads(darktable.num_openmp_threads);
#endif
  dt_loc_init_datadir(datadir_from_command);
  dt_loc_init_plugindir(moduledir_from_command);
  if(dt_loc_init_tmp_dir(tmpdir_from_command))
  {
    printf(_("ERROR : invalid temporary directory : %s\n"),darktable.tmpdir);
    return usage(argv[0]);
  }
  dt_loc_init_user_config_dir(configdir_from_command);
  dt_loc_init_user_cache_dir(cachedir_from_command);

#if !GLIB_CHECK_VERSION(2, 35, 0)
  g_type_init();
#endif

  // does not work, as gtk is not inited yet.
  // even if it were, it's a super bad idea to invoke gtk stuff from
  // a signal handler.
  /* check cput caps */
  // dt_check_cpu(argc,argv);

#ifdef HAVE_GEGL
  char geglpath[PATH_MAX];
  char datadir[PATH_MAX];
  dt_loc_get_datadir(datadir, sizeof(datadir));
  snprintf(geglpath, sizeof(geglpath), "%s/gegl:/usr/lib/gegl-0.0", datadir);
  (void)setenv("GEGL_PATH", geglpath, 1);
  gegl_init(&argc, &argv);
#endif
#ifdef USE_LUA
  dt_lua_init_early(NULL);
#endif

  // thread-safe init:
  dt_exif_init();
  char datadir[PATH_MAX];
  dt_loc_get_user_config_dir (datadir, sizeof(datadir));
  char filename[PATH_MAX];
  snprintf(filename, sizeof(filename), "%s/darktablerc", datadir);

  // initialize the config backend. this needs to be done first...
  darktable.conf = (dt_conf_t *)calloc(1, sizeof(dt_conf_t));
  dt_conf_init(darktable.conf, filename, config_override);
  g_slist_free_full(config_override, g_free);

  // set the interface language
  const gchar* lang = dt_conf_get_string("ui_last/gui_language"); // we may not g_free 'lang' since it is owned by setlocale afterwards
  if(lang != NULL && lang[0] != '\0')
  {
    if(setlocale(LC_ALL, lang) != NULL)
      gtk_disable_setlocale();
  }

  // initialize the database
  darktable.db = dt_database_init(dbfilename_from_command);
  if(darktable.db == NULL)
  {
    printf("ERROR : cannot open database\n");
    return 1;
  }
  else if(!dt_database_get_lock_acquired(darktable.db))
  {
    // send the images to the other instance via dbus
    if(images_to_load)
    {
      GSList *p = images_to_load;

      // get a connection!
      GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SESSION,NULL, NULL);

      while (p != NULL)
      {
        // make the filename absolute ...
        gchar *filename = dt_make_path_absolute((gchar*)p->data);
        if(filename == NULL) continue;
        // ... and send it to the running instance of darktable
        g_dbus_connection_call_sync(connection,
                                    "org.darktable.service",
                                    "/darktable",
                                    "org.darktable.service.Remote",
                                    "Open",
                                    g_variant_new ("(s)", filename),
                                    NULL,
                                    G_DBUS_CALL_FLAGS_NONE,
                                    -1,
                                    NULL,
                                    NULL);
        p = g_slist_next(p);
        g_free(filename);
      }

      g_slist_free(images_to_load);
      g_object_unref(connection);
    }

    return 1;
  }

  // Initialize the signal system
  darktable.signals = dt_control_signal_init();

  // Make sure that the database and xmp files are in sync before starting the fswatch.
  // We need conf and db to be up and running for that which is the case here.
  // FIXME: is this also useful in non-gui mode?
  GList *changed_xmp_files = NULL;
  if(init_gui && dt_conf_get_bool("run_crawler_on_start"))
  {
    changed_xmp_files = dt_control_crawler_run();
  }

  // Initialize the filesystem watcher
  darktable.fswatch=dt_fswatch_new();

#ifdef HAVE_GPHOTO2
  // Initialize the camera control
  darktable.camctl=dt_camctl_new();
#endif

  // get max lighttable thumbnail size:
  darktable.thumbnail_width  = CLAMPS(dt_conf_get_int("plugins/lighttable/thumbnail_width"),  200, 3000);
  darktable.thumbnail_height = CLAMPS(dt_conf_get_int("plugins/lighttable/thumbnail_height"), 200, 3000);
  // and make sure it can be mip-mapped all the way from mip4 to mip0
  darktable.thumbnail_width  /= 16;
  darktable.thumbnail_width  *= 16;
  darktable.thumbnail_height /= 16;
  darktable.thumbnail_height *= 16;

  // Initialize the password storage engine
  darktable.pwstorage=dt_pwstorage_new();

  // FIXME: move there into dt_database_t
  dt_pthread_mutex_init(&(darktable.db_insert), NULL);
  dt_pthread_mutex_init(&(darktable.plugin_threadsafe), NULL);
  dt_pthread_mutex_init(&(darktable.capabilities_threadsafe), NULL);
  darktable.control = (dt_control_t *)calloc(1, sizeof(dt_control_t));
  if(init_gui)
  {
    dt_control_init(darktable.control);
  }
  else
  {
    if(dbfilename_from_command && !strcmp(dbfilename_from_command, ":memory:"))
      dt_gui_presets_init(); // init preset db schema.
    darktable.control->running = 0;
    darktable.control->accelerators = NULL;
    dt_pthread_mutex_init(&darktable.control->run_mutex, NULL);
  }

  // initialize collection query
  darktable.collection_listeners = NULL;
  darktable.collection = dt_collection_new(NULL);

  /* initialize selection */
  darktable.selection = dt_selection_new();

  /* capabilities set to NULL */
  darktable.capabilities = NULL;

#ifdef HAVE_GRAPHICSMAGICK
  /* GraphicsMagick init */
  InitializeMagick(darktable.progname);
#endif

  darktable.opencl = (dt_opencl_t *)calloc(1, sizeof(dt_opencl_t));
#ifdef HAVE_OPENCL
  dt_opencl_init(darktable.opencl, argc, argv);
#endif

  darktable.blendop = (dt_blendop_t *)calloc(1, sizeof(dt_blendop_t));
  dt_develop_blend_init(darktable.blendop);

  darktable.points = (dt_points_t *)calloc(1, sizeof(dt_points_t));
  dt_points_init(darktable.points, dt_get_num_threads());

  // must come before mipmap_cache, because that one will need to access
  // image dimensions stored in here:
  darktable.image_cache = (dt_image_cache_t *)calloc(1, sizeof(dt_image_cache_t));
  dt_image_cache_init(darktable.image_cache);

  darktable.mipmap_cache = (dt_mipmap_cache_t *)calloc(1, sizeof(dt_mipmap_cache_t));
  dt_mipmap_cache_init(darktable.mipmap_cache);

  // The GUI must be initialized before the views, because the init()
  // functions of the views depend on darktable.control->accels_* to register
  // their keyboard accelerators

  if(init_gui)
  {
    darktable.gui = (dt_gui_gtk_t *)calloc(1, sizeof(dt_gui_gtk_t));
    if(dt_gui_gtk_init(darktable.gui, argc, argv)) return 1;
    dt_bauhaus_init();
  }
  else darktable.gui = NULL;

  darktable.view_manager = (dt_view_manager_t *)calloc(1, sizeof(dt_view_manager_t));
  dt_view_manager_init(darktable.view_manager);

  // load the darkroom mode plugins once:
  dt_iop_load_modules_so();

  if(init_gui)
  {
    darktable.lib = (dt_lib_t *)calloc(1, sizeof(dt_lib_t));
    dt_lib_init(darktable.lib);

    dt_control_load_config(darktable.control);
  }
  darktable.imageio = (dt_imageio_t *)calloc(1, sizeof(dt_imageio_t));
  dt_imageio_init(darktable.imageio);

  if(init_gui)
  {
    // Loading the keybindings
    char keyfile[PATH_MAX];

    // First dump the default keymapping
    snprintf(keyfile, sizeof(keyfile), "%s/keyboardrc_default", datadir);
    gtk_accel_map_save(keyfile);

    // Removing extraneous semi-colons from the default keymap
    strip_semicolons_from_keymap(keyfile);

    // Then load any modified keys if available
    snprintf(keyfile, sizeof(keyfile), "%s/keyboardrc", datadir);
    if(g_file_test(keyfile, G_FILE_TEST_EXISTS))
      gtk_accel_map_load(keyfile);
    else
      gtk_accel_map_save(keyfile); // Save the default keymap if none is present

    // I doubt that connecting to dbus for darktable-cli makes sense
    darktable.dbus = dt_dbus_init();

    // initialize undo struct
    darktable.undo = dt_undo_init();

    // load image(s) specified on cmdline
    int id = 0;
    if(images_to_load)
    {
      // If only one image is listed, attempt to load it in darkroom
      gboolean load_in_dr = (g_slist_next(images_to_load) == NULL);
      GSList *p = images_to_load;

      while (p != NULL)
      {
        // don't put these function calls into MAX(), the macro will evaluate
        // it twice (and happily deadlock, in this particular case)
        int newid = dt_load_from_string((gchar*)p->data, load_in_dr);
        id = MAX(id, newid);
        p = g_slist_next(p);
      }

      if (!load_in_dr || id == 0)
        dt_ctl_switch_mode_to(DT_LIBRARY);

      g_slist_free(images_to_load);
    }
    else
      dt_ctl_switch_mode_to(DT_LIBRARY);
  }

  if(darktable.unmuted & DT_DEBUG_MEMORY)
  {
    fprintf(stderr, "[memory] after successful startup\n");
    dt_print_mem_usage();
  }

  dt_image_local_copy_synch();

  /* init lua last, since it's user made stuff it must be in the real environment */
#ifdef USE_LUA
  dt_lua_init(darktable.lua_state.state,init_gui);
#endif

  // last but not least construct the popup that asks the user about images whose xmp files are newer than the db entry
  if(init_gui && changed_xmp_files)
  {
    dt_control_crawler_show_image_list(changed_xmp_files);
  }

  return 0;
}
Exemple #23
0
static void
portal_add_named (GDBusMethodInvocation *invocation,
                  GVariant *parameters,
                  const char *app_id)
{
  GDBusMessage *message;
  GUnixFDList *fd_list;
  g_autofree char *id = NULL;
  g_autofree char *proc_path = NULL;
  int parent_fd_id, parent_fd, fds_len, fd_flags;
  const int *fds;
  char parent_path_buffer[PATH_MAX+1];
  g_autofree char *path = NULL;
  ssize_t symlink_size;
  struct stat parent_st_buf;
  const char *filename;
  gboolean reuse_existing, persistent;
  g_autoptr(GVariant) filename_v = NULL;

  g_variant_get (parameters, "(h@aybb)", &parent_fd_id, &filename_v, &reuse_existing, &persistent);
  filename = g_variant_get_bytestring (filename_v);

  /* This is only allowed from the host, or else we could leak existance of files */
  if (*app_id != 0)
    {
      g_dbus_method_invocation_return_error (invocation, XDG_APP_PORTAL_ERROR, XDG_APP_PORTAL_ERROR_NOT_ALLOWED,
                                             "Not enough permissions");
      return;
    }

  message = g_dbus_method_invocation_get_message (invocation);
  fd_list = g_dbus_message_get_unix_fd_list (message);

  parent_fd = -1;
  if (fd_list != NULL)
    {
      fds = g_unix_fd_list_peek_fds (fd_list, &fds_len);
      if (parent_fd_id < fds_len)
        parent_fd = fds[parent_fd_id];
    }

  if (strchr (filename, '/') != NULL)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             XDG_APP_PORTAL_ERROR, XDG_APP_PORTAL_ERROR_INVALID_ARGUMENT,
                                             "Invalid filename passed");
      return;
    }

  proc_path = g_strdup_printf ("/proc/self/fd/%d", parent_fd);

  if (parent_fd == -1 ||
      /* Must be able to get fd flags */
      (fd_flags = fcntl (parent_fd, F_GETFL)) == -1 ||
      /* Must be O_PATH */
      ((fd_flags & O_PATH) != O_PATH) ||
      /* Must not be O_NOFOLLOW (because we want the target file) */
      ((fd_flags & O_NOFOLLOW) == O_PATH) ||
      /* Must be able to fstat */
      fstat (parent_fd, &parent_st_buf) < 0 ||
      /* Must be a directory file */
      (parent_st_buf.st_mode & S_IFMT) != S_IFDIR ||
      /* Must be able to read path from /proc/self/fd */
      /* This is an absolute and (at least at open time) symlink-expanded path */
      (symlink_size = readlink (proc_path, parent_path_buffer, sizeof (parent_path_buffer) - 1)) < 0)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             XDG_APP_PORTAL_ERROR, XDG_APP_PORTAL_ERROR_INVALID_ARGUMENT,
                                             "Invalid fd passed");
      return;
    }

  if (parent_st_buf.st_dev == fuse_dev)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             XDG_APP_PORTAL_ERROR, XDG_APP_PORTAL_ERROR_INVALID_ARGUMENT,
                                             "Invalid fd passed");
      return;
    }

  parent_path_buffer[symlink_size] = 0;

  path = g_build_filename (parent_path_buffer, filename, NULL);

  g_debug ("portal_add_named %s", path);

  AUTOLOCK(db);

  id = do_create_doc (&parent_st_buf, path, reuse_existing, persistent);

  g_dbus_method_invocation_return_value (invocation,
                                         g_variant_new ("(s)", id));
}
static void
nm_ip_up (void *data, int arg)
{
	guint32 pppd_made_up_address = htonl (0x0a404040 + ifunit);
	ipcp_options opts = ipcp_gotoptions[0];
	ipcp_options peer_opts = ipcp_hisoptions[0];
	GVariantBuilder builder;

	g_return_if_fail (G_IS_DBUS_PROXY (gl.proxy));

	_LOGI ("ip-up: event");

	if (!opts.ouraddr) {
		_LOGW ("ip-up: didn't receive an internal IP from pppd!");
		nm_phasechange (NULL, PHASE_DEAD);
		return;
	}

	g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);

	g_variant_builder_add (&builder, "{sv}",
	                       NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV,
	                       g_variant_new_string (ifname));

	g_variant_builder_add (&builder, "{sv}",
	                       NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS,
	                       g_variant_new_uint32 (opts.ouraddr));

	/* Prefer the peer options remote address first, _unless_ pppd made the
	 * address up, at which point prefer the local options remote address,
	 * and if that's not right, use the made-up address as a last resort.
	 */
	if (peer_opts.hisaddr && (peer_opts.hisaddr != pppd_made_up_address)) {
		g_variant_builder_add (&builder, "{sv}",
		                       NM_VPN_PLUGIN_IP4_CONFIG_PTP,
		                       g_variant_new_uint32 (peer_opts.hisaddr));
	} else if (opts.hisaddr) {
		g_variant_builder_add (&builder, "{sv}",
		                       NM_VPN_PLUGIN_IP4_CONFIG_PTP,
		                       g_variant_new_uint32 (opts.hisaddr));
	} else if (peer_opts.hisaddr == pppd_made_up_address) {
		/* As a last resort, use the made-up address */
		g_variant_builder_add (&builder, "{sv}",
		                       NM_VPN_PLUGIN_IP4_CONFIG_PTP,
		                       g_variant_new_uint32 (peer_opts.ouraddr));
	}

	g_variant_builder_add (&builder, "{sv}",
	                       NM_VPN_PLUGIN_IP4_CONFIG_PREFIX,
	                       g_variant_new_uint32 (32));

	if (opts.dnsaddr[0] || opts.dnsaddr[1]) {
		guint32 dns[2];
		int len = 0;

		if (opts.dnsaddr[0])
			dns[len++] = opts.dnsaddr[0];
		if (opts.dnsaddr[1])
			dns[len++] = opts.dnsaddr[1];

		g_variant_builder_add (&builder, "{sv}",
		                       NM_VPN_PLUGIN_IP4_CONFIG_DNS,
		                       g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
		                                                  dns, len, sizeof (guint32)));
	}

	_LOGI ("ip-up: sending Ip4Config to NetworkManager-l2tp...");

	g_dbus_proxy_call (gl.proxy,
	                   "SetIp4Config",
	                   g_variant_new ("(a{sv})", &builder),
	                   G_DBUS_CALL_FLAGS_NONE, -1,
	                   NULL,
	                   NULL, NULL);
}
void
gdu_partition_dialog_show (GduWindow    *window,
                           UDisksObject *object)
{
  EditPartitionData *data;
  gint response;

  data = g_new0 (EditPartitionData, 1);
  data->window = g_object_ref (window);
  data->object = g_object_ref (object);
  data->partition = udisks_object_get_partition (object);
  g_assert (data->partition != NULL);
  data->partition_table = udisks_client_get_partition_table (gdu_window_get_client (window), data->partition);
  g_assert (data->partition_table != NULL);
  data->partition_table_type = udisks_partition_table_dup_type_ (data->partition_table);

  if (g_strcmp0 (data->partition_table_type, "gpt") == 0)
    {
      data->dialog = GTK_WIDGET (gdu_application_new_widget (gdu_window_get_application (window),
                                                             "edit-gpt-partition-dialog.ui",
                                                             "edit-gpt-partition-dialog",
                                                             &data->builder));
      data->name_entry = GTK_WIDGET (gtk_builder_get_object (data->builder, "name-entry"));
      data->system_checkbutton = GTK_WIDGET (gtk_builder_get_object (data->builder, "system-checkbutton"));
      data->hide_from_firmware_checkbutton = GTK_WIDGET (gtk_builder_get_object (data->builder,
                                                                                 "hide-from-firmware-checkbutton"));
      data->bootable_checkbutton = GTK_WIDGET (gtk_builder_get_object (data->builder, "bootable-checkbutton"));

      g_signal_connect (data->name_entry,
                        "notify::text", G_CALLBACK (edit_partition_property_changed), data);
      g_signal_connect (data->system_checkbutton,
                        "notify::active", G_CALLBACK (edit_partition_property_changed), data);
      g_signal_connect (data->hide_from_firmware_checkbutton,
                        "notify::active", G_CALLBACK (edit_partition_property_changed), data);
      g_signal_connect (data->bootable_checkbutton,
                        "notify::active", G_CALLBACK (edit_partition_property_changed), data);
    }
  else if (g_strcmp0 (data->partition_table_type, "dos") == 0)
    {
      data->dialog = GTK_WIDGET (gdu_application_new_widget (gdu_window_get_application (window),
                                                             "edit-dos-partition-dialog.ui",
                                                             "edit-dos-partition-dialog",
                                                             &data->builder));
      data->bootable_checkbutton = GTK_WIDGET (gtk_builder_get_object (data->builder, "bootable-checkbutton"));
      g_signal_connect (data->bootable_checkbutton,
                        "notify::active", G_CALLBACK (edit_partition_property_changed), data);
    }
  else
    {
      data->dialog = GTK_WIDGET (gdu_application_new_widget (gdu_window_get_application (window),
                                                             "edit-partition-dialog.ui",
                                                             "edit-partition-dialog",
                                                             &data->builder));
    }
  data->type_combobox = GTK_WIDGET (gtk_builder_get_object (data->builder, "type-combobox"));
  g_signal_connect (data->type_combobox,
                    "notify::active", G_CALLBACK (edit_partition_property_changed), data);

  gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (window));
  gtk_dialog_set_default_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK);

  edit_partition_populate (data);
  edit_partition_update (data);

  gtk_widget_show_all (data->dialog);
  gtk_widget_grab_focus (data->type_combobox);

  /* TODO: do this async */
  response = gtk_dialog_run (GTK_DIALOG (data->dialog));
  if (response == GTK_RESPONSE_OK)
    {
      gchar *type;
      gchar *name;
      guint64 flags;
      GError *error;

      edit_partition_get (data, &type, &name, &flags);

      if (g_strcmp0 (udisks_partition_get_type_ (data->partition), type) != 0)
        {
          error = NULL;
          if (!udisks_partition_call_set_type_sync (data->partition,
                                                    type,
                                                    g_variant_new ("a{sv}", NULL), /* options */
                                                    NULL, /* GCancellable */
                                                    &error))
            {
              gdu_utils_show_error (GTK_WINDOW (window), _("Error setting partition type"), error);
              g_error_free (error);
              goto set_out;
            }
        }
      if (g_strcmp0 (udisks_partition_get_name (data->partition), name) != 0)
        {
          error = NULL;
          if (!udisks_partition_call_set_name_sync (data->partition,
                                                    name,
                                                    g_variant_new ("a{sv}", NULL), /* options */
                                                    NULL, /* GCancellable */
                                                    &error))
            {
              gdu_utils_show_error (GTK_WINDOW (window), _("Error setting partition name"), error);
              g_error_free (error);
              goto set_out;
            }
        }
      if (udisks_partition_get_flags (data->partition) != flags)
        {
          error = NULL;
          if (!udisks_partition_call_set_flags_sync (data->partition,
                                                     flags,
                                                     g_variant_new ("a{sv}", NULL), /* options */
                                                     NULL, /* GCancellable */
                                                     &error))
            {
              gdu_utils_show_error (GTK_WINDOW (window), _("Error setting partition flags"), error);
              g_error_free (error);
              goto set_out;
            }
        }
    set_out:
      g_free (type);
      g_free (name);
    }

  edit_partition_data_free (data);
}
static void
nm_phasechange (void *data, int arg)
{
	NMPPPStatus ppp_status = NM_PPP_STATUS_UNKNOWN;
	char *ppp_phase;

	g_return_if_fail (G_IS_DBUS_PROXY (gl.proxy));

	switch (arg) {
	case PHASE_DEAD:
		ppp_status = NM_PPP_STATUS_DEAD;
		ppp_phase = "dead";
		break;
	case PHASE_INITIALIZE:
		ppp_status = NM_PPP_STATUS_INITIALIZE;
		ppp_phase = "initialize";
		break;
	case PHASE_SERIALCONN:
		ppp_status = NM_PPP_STATUS_SERIALCONN;
		ppp_phase = "serial connection";
		break;
	case PHASE_DORMANT:
		ppp_status = NM_PPP_STATUS_DORMANT;
		ppp_phase = "dormant";
		break;
	case PHASE_ESTABLISH:
		ppp_status = NM_PPP_STATUS_ESTABLISH;
		ppp_phase = "establish";
		break;
	case PHASE_AUTHENTICATE:
		ppp_status = NM_PPP_STATUS_AUTHENTICATE;
		ppp_phase = "authenticate";
		break;
	case PHASE_CALLBACK:
		ppp_status = NM_PPP_STATUS_CALLBACK;
		ppp_phase = "callback";
		break;
	case PHASE_NETWORK:
		ppp_status = NM_PPP_STATUS_NETWORK;
		ppp_phase = "network";
		break;
	case PHASE_RUNNING:
		ppp_status = NM_PPP_STATUS_RUNNING;
		ppp_phase = "running";
		break;
	case PHASE_TERMINATE:
		ppp_status = NM_PPP_STATUS_TERMINATE;
		ppp_phase = "terminate";
		break;
	case PHASE_DISCONNECT:
		ppp_status = NM_PPP_STATUS_DISCONNECT;
		ppp_phase = "disconnect";
		break;
	case PHASE_HOLDOFF:
		ppp_status = NM_PPP_STATUS_HOLDOFF;
		ppp_phase = "holdoff";
		break;
	case PHASE_MASTER:
		ppp_status = NM_PPP_STATUS_MASTER;
		ppp_phase = "master";
		break;

	default:
		ppp_phase = "unknown";
		break;
	}

	_LOGI ("phasechange: status %d / phase '%s'",
	       ppp_status, ppp_phase);

	if (ppp_status != NM_PPP_STATUS_UNKNOWN) {
		g_dbus_proxy_call (gl.proxy,
		                   "SetState",
		                   g_variant_new ("(u)", ppp_status),
		                   G_DBUS_CALL_FLAGS_NONE, -1,
		                   NULL,
		                   NULL, NULL);
	}
}
Exemple #27
0
static gboolean
handle_service_action (CockpitServices *object,
                       GDBusMethodInvocation *invocation,
                       const gchar *arg_name,
                       const gchar *arg_action)
{
  Services *services = SERVICES (object);

  if (!auth_check_sender_role (invocation, COCKPIT_ROLE_ADMIN))
    return TRUE;

  if (services->systemd == NULL)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             COCKPIT_ERROR, COCKPIT_ERROR_FAILED,
                                             "systemd not running");
      return TRUE;
    }

  const gchar *method = NULL;
  int flags = 0;

  for (int i = 0; action_methods[i].action; i++)
    {
      if (strcmp (action_methods[i].action, arg_action) == 0)
        {
          method = action_methods[i].method;
          flags = action_methods[i].flags;
          break;
        }
    }

  if (method == NULL)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             COCKPIT_ERROR, COCKPIT_ERROR_FAILED,
                                             "Unsupported action: %s",
                                             arg_action);
      return TRUE;
    }

  const gchar *mode = (flags & ISOLATE) ? "isolate" : "replace";

  ServiceActionData *data = g_new0(ServiceActionData, 1);
  data->services = services;
  data->invocation = invocation;
  data->flags = flags;

  GVariant *args;
  if (flags & FOR_FILES)
    {
      const gchar *files[] = { arg_name, NULL };
      if ((flags & FORCE) || (flags & NO_FORCE))
        args = g_variant_new ("(^asbb)", files, FALSE, flags & FORCE);
      else
        args = g_variant_new ("(^asb)", files, FALSE);
    }
  else
    args = g_variant_new ("(ss)", arg_name, mode);

  g_dbus_proxy_call (services->systemd,
                     method,
                     args,
                     G_DBUS_CALL_FLAGS_NONE,
                     G_MAXINT,
                     NULL,
                     on_service_action_done,
                     data);
  return TRUE;
}
Exemple #28
0
static void abrt_p2_task_init(AbrtP2Task *self)
{
    self->pv = abrt_p2_task_get_instance_private(self);
    self->pv->p2t_details = g_variant_new("a{sv}", NULL);
}
/**
 * gpm_control_suspend:
 **/
gboolean
gpm_control_suspend (GpmControl *control, GError **error)
{
	gboolean allowed;
	gboolean ret = FALSE;
	gboolean do_lock;
	gboolean nm_sleep;
	GpmScreensaver *screensaver;
	guint32 throttle_cookie = 0;
#ifdef WITH_KEYRING
	gboolean lock_mate_keyring;
	MateKeyringResult keyres;
#endif /* WITH_KEYRING */
#ifdef WITH_SYSTEMD_SLEEP
	GError *dbus_error = NULL;
	DBusGProxy *proxy;
	GVariant *res;
#endif

	screensaver = gpm_screensaver_new ();
#ifndef WITH_SYSTEMD_SLEEP
	g_object_get (control->priv->client,
		      "can-suspend", &allowed,
		      NULL);
	if (!allowed) {
		egg_debug ("cannot suspend as not allowed from policy");
		g_set_error_literal (error, GPM_CONTROL_ERROR, GPM_CONTROL_ERROR_GENERAL, "Cannot suspend");
		goto out;
	}
#endif

#ifdef WITH_KEYRING
	/* we should perhaps lock keyrings when sleeping #375681 */
	lock_mate_keyring = g_settings_get_boolean (control->priv->settings, GPM_SETTINGS_LOCK_KEYRING_SUSPEND);
	if (lock_mate_keyring) {
		keyres = mate_keyring_lock_all_sync ();
		if (keyres != MATE_KEYRING_RESULT_OK)
			egg_warning ("could not lock keyring");
	}
#endif /* WITH_KEYRING */

	do_lock = gpm_control_get_lock_policy (control, GPM_SETTINGS_LOCK_ON_SUSPEND);
	if (do_lock) {
		throttle_cookie = gpm_screensaver_add_throttle (screensaver, "suspend");
		gpm_screensaver_lock (screensaver);
	}

	nm_sleep = g_settings_get_boolean (control->priv->settings, GPM_SETTINGS_NETWORKMANAGER_SLEEP);
	if (nm_sleep)
		gpm_networkmanager_sleep ();

	/* Do the suspend */
	egg_debug ("emitting sleep");
	g_signal_emit (control, signals [SLEEP], 0, GPM_CONTROL_ACTION_SUSPEND);

#ifdef WITH_SYSTEMD_SLEEP
	/* sleep via logind */
	proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
			G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
			NULL,
			"org.freedesktop.login1",
			"/org/freedesktop/login1",
			"org.freedesktop.login1.Manager",
			NULL,
			&dbus_error );
    if (proxy == NULL) {
        egg_error("Error connecting to dbus - %s", dbus_error->message);
        g_error_free (dbus_error);
        return -1;
    }
    g_dbus_proxy_call_sync (proxy, "Suspend", 
                            g_variant_new( "(b)",FALSE),
                            G_DBUS_CALL_FLAGS_NONE,
                            -1,
                            NULL,
                            &dbus_error
                            );
    if (dbus_error != NULL ) {
	    egg_debug ("Error in dbus - %s", dbus_error->message);
	    g_error_free (dbus_error);
	    ret = TRUE;
    }
    else {
	    ret = TRUE;
    }
    g_object_unref(proxy);
#else
	ret = up_client_suspend_sync (control->priv->client, NULL, error);
#endif

	egg_debug ("emitting resume");
	g_signal_emit (control, signals [RESUME], 0, GPM_CONTROL_ACTION_SUSPEND);

	if (do_lock) {
		gpm_screensaver_poke (screensaver);
		if (throttle_cookie)
			gpm_screensaver_remove_throttle (screensaver, throttle_cookie);
	}

	nm_sleep = g_settings_get_boolean (control->priv->settings, GPM_SETTINGS_NETWORKMANAGER_SLEEP);
	if (nm_sleep)
		gpm_networkmanager_wake ();

out:
	g_object_unref (screensaver);
	return ret;
}
static void
gtk_application_impl_dbus_startup (GtkApplicationImpl *impl,
                                   gboolean            register_session)
{
  GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
  static gchar *client_id;
  GError *error = NULL;
  GVariant *res;

  dbus->session = g_application_get_dbus_connection (G_APPLICATION (impl->application));

  if (!dbus->session)
    return;

  dbus->application_id = g_application_get_application_id (G_APPLICATION (impl->application));
  dbus->object_path = g_application_get_dbus_object_path (G_APPLICATION (impl->application));
  dbus->unique_name = g_dbus_connection_get_unique_name (dbus->session);

  if (client_id == NULL)
    {
      const gchar *desktop_autostart_id;

      desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
      /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
       * use the same client id.
       */
      g_unsetenv ("DESKTOP_AUTOSTART_ID");
      client_id = g_strdup (desktop_autostart_id ? desktop_autostart_id : "");
    }

  g_debug ("Connecting to session manager");

  dbus->sm_proxy = g_dbus_proxy_new_sync (dbus->session,
                                          G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
                                          G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
                                          NULL,
                                          "org.gnome.SessionManager",
                                          "/org/gnome/SessionManager",
                                          "org.gnome.SessionManager",
                                          NULL,
                                          &error);

  if (error)
    {
      g_warning ("Failed to get a session proxy: %s", error->message);
      g_error_free (error);
      return;
    }

  /* FIXME: should we reuse the D-Bus application id here ? */
  dbus->app_id = g_strdup (g_get_prgname ());

  if (!register_session)
    return;

  g_debug ("Registering client '%s' '%s'", dbus->app_id, client_id);

  res = g_dbus_proxy_call_sync (dbus->sm_proxy,
                                "RegisterClient",
                                g_variant_new ("(ss)", dbus->app_id, client_id),
                                G_DBUS_CALL_FLAGS_NONE,
                                G_MAXINT,
                                NULL,
                                &error);

  if (error)
    {
      g_warning ("Failed to register client: %s", error->message);
      g_error_free (error);
      g_clear_object (&dbus->sm_proxy);
      return;
    }

  g_variant_get (res, "(o)", &dbus->client_path);
  g_variant_unref (res);

  g_debug ("Registered client at '%s'", dbus->client_path);

  dbus->client_proxy = g_dbus_proxy_new_sync (dbus->session, 0,
                                              NULL,
                                              "org.gnome.SessionManager",
                                              dbus->client_path,
                                              "org.gnome.SessionManager.ClientPrivate",
                                              NULL,
                                              &error);
  if (error)
    {
      g_warning ("Failed to get client proxy: %s", error->message);
      g_error_free (error);
      g_clear_object (&dbus->sm_proxy);
      g_free (dbus->client_path);
      dbus->client_path = NULL;
      return;
    }

  g_signal_connect (dbus->client_proxy, "g-signal", G_CALLBACK (client_proxy_signal), dbus);
}