<commit_before>/*
 * gvfs/monitor/afc/afc-volume.c
 *
 * Copyright (c) 2008 <NAME> <<EMAIL>>
 */

#include <config.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <gio/gio.h>
#include <glib/gi18n.h>

#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/lockdown.h>

#include "afcvolume.h"

struct _GVfsAfcVolume {
  GObject parent;

  GVolumeMonitor *monitor;

  char *uuid;
  char *service;

  char *name;
  char *icon;
  char *symbolic_icon;
  char *icon_fallback;
};

static void g_vfs_afc_volume_iface_init (GVolumeIface *iface);

G_DEFINE_TYPE_EXTENDED(GVfsAfcVolume, g_vfs_afc_volume, G_TYPE_OBJECT, 0,
                       G_IMPLEMENT_INTERFACE(G_TYPE_VOLUME, g_vfs_afc_volume_iface_init))

static void
g_vfs_afc_volume_finalize (GObject *object)
{
  GVfsAfcVolume *self = NULL;

  self = G_VFS_AFC_VOLUME(object);

  g_free (self->uuid);
  g_free (self->service);

  g_free (self->name);
  g_free (self->icon);
  g_free (self->symbolic_icon);
  g_free (self->icon_fallback);

  if (G_OBJECT_CLASS(g_vfs_afc_volume_parent_class)->finalize)
    (*G_OBJECT_CLASS(g_vfs_afc_volume_parent_class)->finalize) (G_OBJECT(self));
}

static void
g_vfs_afc_volume_init (GVfsAfcVolume *self)
{
  GVfsAfcVolume *afc_volume = G_VFS_AFC_VOLUME (self);

  afc_volume->name = g_strdup ("iPhone");
  afc_volume->icon = g_strdup ("phone-apple-iphone");
  afc_volume->symbolic_icon = g_strdup ("phone-apple-iphone-symbolic");
}

static void
g_vfs_afc_volume_class_init (GVfsAfcVolumeClass *klass)
{
  GObjectClass *gobject_class;
  gobject_class = G_OBJECT_CLASS(klass);
  gobject_class->finalize = g_vfs_afc_volume_finalize;
}

static gboolean
_g_vfs_afc_volume_check_house_arrest_version (lockdownd_client_t lockdown_cli)
{
  plist_t value;
  lockdownd_error_t lerr;
  gboolean retval;

  value = NULL;
  retval = FALSE;

  lerr = lockdownd_get_value (lockdown_cli, NULL, "ProductVersion", &value);
  if (G_LIKELY(lerr == LOCKDOWN_E_SUCCESS))
    {
      if (plist_get_node_type(value) == PLIST_STRING)
        {
          char *version_string = NULL;

          plist_get_string_val(value, &version_string);
          if (version_string)
            {
              /* parse version */
              int maj = 0;
              int min = 0;
              int rev = 0;

              sscanf(version_string, "%d.%d.%d", &maj, &min, &rev);
              free(version_string);

              if (maj > 3)
                {
                    retval = TRUE;
                }
              else if (maj == 3)
                {
                  if (min > 1)
                        retval = TRUE;
                  if (min == 1 && rev >= 2)
                        retval = TRUE;
              }
            }
        }
    }

  return retval;
}

static int
_g_vfs_afc_volume_update_metadata (GVfsAfcVolume *self)
{
  idevice_t dev;
  lockdownd_client_t lockdown_cli = NULL;
  idevice_error_t err;
  guint retries;
  plist_t value;
  char *model, *display_name;
  lockdownd_service_descriptor_t lockdown_service = NULL;
  lockdownd_error_t lerr;

  retries = 0;
  do {
      err = idevice_new (&dev, self->uuid);
      if (err == IDEVICE_E_SUCCESS)
        break;
      g_usleep (G_USEC_PER_SEC);
  } while (retries++ < 10);

  if (err != IDEVICE_E_SUCCESS)
    {
      g_debug ("Failed to initialise an idevice_t (%d)\n", err);
      return 0;
    }

  if (self->service != NULL)
    {
      if (lockdownd_client_new_with_handshake (dev, &lockdown_cli, "gvfs-afc-volume-monitor") != LOCKDOWN_E_SUCCESS)
        {
          idevice_free (dev);
          return 0;
        }
      if (!_g_vfs_afc_volume_check_house_arrest_version (lockdown_cli))
        {
          lockdownd_service_descriptor_free (lockdown_service);
          idevice_free (dev);
          return 0;
        }
      lerr = lockdownd_start_service(lockdown_cli, "com.apple.mobile.house_arrest", &lockdown_service);
      lockdownd_service_descriptor_free (lockdown_service);
      if (lerr != LOCKDOWN_E_SUCCESS)
        {
          g_warning ("Couldn't start com.apple.mobile.house_arrest for UUID %s: %d", self->uuid, lerr);
          idevice_free (dev);
          return 0;
        }
    }
  else
    {
      if (lockdownd_client_new (dev, &lockdown_cli, "gvfs-afc-volume-monitor") != LOCKDOWN_E_SUCCESS)
        {
          idevice_free (dev);
          return 0;
        }
    }

  /* try to use pretty device name */
  if (lockdownd_get_device_name (lockdown_cli, &display_name) == LOCKDOWN_E_SUCCESS)
    {
      g_free (self->name);
      if (g_strcmp0 (self->service, HOUSE_ARREST_SERVICE_PORT) == 0)<commit_msg>afc: Fix volume init with a locked device<commit_after>/*
 * gvfs/monitor/afc/afc-volume.c
 *
 * Copyright (c) 2008 <NAME> <<EMAIL>>
 */

#include <config.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <gio/gio.h>
#include <glib/gi18n.h>

#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/lockdown.h>

#include "afcvolume.h"

struct _GVfsAfcVolume {
  GObject parent;

  GVolumeMonitor *monitor;

  char *uuid;
  char *service;

  char *name;
  char *icon;
  char *symbolic_icon;
  char *icon_fallback;
};

static void g_vfs_afc_volume_iface_init (GVolumeIface *iface);

G_DEFINE_TYPE_EXTENDED(GVfsAfcVolume, g_vfs_afc_volume, G_TYPE_OBJECT, 0,
                       G_IMPLEMENT_INTERFACE(G_TYPE_VOLUME, g_vfs_afc_volume_iface_init))

static void
g_vfs_afc_volume_finalize (GObject *object)
{
  GVfsAfcVolume *self = NULL;

  self = G_VFS_AFC_VOLUME(object);

  g_free (self->uuid);
  g_free (self->service);

  g_free (self->name);
  g_free (self->icon);
  g_free (self->symbolic_icon);
  g_free (self->icon_fallback);

  if (G_OBJECT_CLASS(g_vfs_afc_volume_parent_class)->finalize)
    (*G_OBJECT_CLASS(g_vfs_afc_volume_parent_class)->finalize) (G_OBJECT(self));
}

static void
g_vfs_afc_volume_init (GVfsAfcVolume *self)
{
  GVfsAfcVolume *afc_volume = G_VFS_AFC_VOLUME (self);

  afc_volume->name = g_strdup ("iPhone");
  afc_volume->icon = g_strdup ("phone-apple-iphone");
  afc_volume->symbolic_icon = g_strdup ("phone-apple-iphone-symbolic");
}

static void
g_vfs_afc_volume_class_init (GVfsAfcVolumeClass *klass)
{
  GObjectClass *gobject_class;
  gobject_class = G_OBJECT_CLASS(klass);
  gobject_class->finalize = g_vfs_afc_volume_finalize;
}

static gboolean
_g_vfs_afc_volume_check_house_arrest_version (lockdownd_client_t lockdown_cli)
{
  plist_t value;
  lockdownd_error_t lerr;
  gboolean retval;

  value = NULL;
  retval = FALSE;

  lerr = lockdownd_get_value (lockdown_cli, NULL, "ProductVersion", &value);
  if (G_LIKELY(lerr == LOCKDOWN_E_SUCCESS))
    {
      if (plist_get_node_type(value) == PLIST_STRING)
        {
          char *version_string = NULL;

          plist_get_string_val(value, &version_string);
          if (version_string)
            {
              /* parse version */
              int maj = 0;
              int min = 0;
              int rev = 0;

              sscanf(version_string, "%d.%d.%d", &maj, &min, &rev);
              free(version_string);

              if (maj > 3)
                {
                    retval = TRUE;
                }
              else if (maj == 3)
                {
                  if (min > 1)
                        retval = TRUE;
                  if (min == 1 && rev >= 2)
                        retval = TRUE;
              }
            }
        }
    }

  return retval;
}

static int
_g_vfs_afc_volume_update_metadata (GVfsAfcVolume *self)
{
  idevice_t dev;
  lockdownd_client_t lockdown_cli = NULL;
  idevice_error_t err;
  guint retries;
  plist_t value;
  char *model, *display_name;
  lockdownd_service_descriptor_t lockdown_service = NULL;
  lockdownd_error_t lerr;

  retries = 0;
  do {
      err = idevice_new (&dev, self->uuid);
      if (err == IDEVICE_E_SUCCESS)
        break;
      g_usleep (G_USEC_PER_SEC);
  } while (retries++ < 10);

  if (err != IDEVICE_E_SUCCESS)
    {
      g_debug ("Failed to initialise an idevice_t (%d)\n", err);
      return 0;
    }

  lerr = lockdownd_client_new (dev, &lockdown_cli, "gvfs-afc-volume-monitor");
  if (lerr != LOCKDOWN_E_SUCCESS)
    {
      g_debug ("Failed to create a client with handshake (%d)\n", lerr);
      idevice_free (dev);
      return 0;
    }

  if (g_strcmp0 (self->service, HOUSE_ARREST_SERVICE_PORT) == 0)
    {
      if (!_g_vfs_afc_volume_check_house_arrest_version (lockdown_cli))
        {
          g_debug ("Failed to check HouseArrest version\n");
          lockdownd_service_descriptor_free (lockdown_service);
          idevice_free (dev);
          return 0;
        }
    }

  /* try to use pretty device name */
  if (lockdownd_get_device_name (lockdown_cli, &display_name) == LOCKDOWN_E_SUCCESS)
    {
      g_free (self->name);
      if (g_strcmp0 (self->service, HOUSE_ARREST_SERVICE_PORT) == 0)
{'fraction_non_alphanumeric': 0.11057367829021372, 'fraction_numerical': 0.00562429696287964, 'mean_word_length': 2.7498945592576973, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 66, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5735820', 'n_tokens_mistral': 3441, 'n_tokens_neox': 3302, 'n_words': 616}