Beispiel #1
0
gboolean
g_vfs_afp_connection_close (GVfsAfpConnection *afp_connection,
                            GCancellable      *cancellable,
                            GError            **error)
{
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
  
  guint16 req_id;
  gboolean res;
  
  /* close DSI session */
  req_id = get_request_id (afp_connection);
  res = send_request_sync (g_io_stream_get_output_stream (priv->conn),
                           DSI_CLOSE_SESSION, req_id, 0, 0, NULL,
                           cancellable, error);
  if (!res)
  {
    g_io_stream_close (priv->conn, cancellable, NULL);
    g_object_unref (priv->conn);
    return FALSE;
  }

  res = g_io_stream_close (priv->conn, cancellable, error);
  g_object_unref (priv->conn);
  
  return res;
}
Beispiel #2
0
GVfsAfpReply *
g_vfs_afp_connection_get_server_info (GVfsAfpConnection *afp_connection,
                                      GCancellable *cancellable,
                                      GError **error)
{
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
  
  GSocketClient *client;
  GIOStream *conn;
  gboolean res;
  DSIHeader dsi_header;
  char *data;

  client = g_socket_client_new ();
  conn = G_IO_STREAM (g_socket_client_connect (client, priv->addr, cancellable, error));
  g_object_unref (client);

  if (!conn)
    return NULL;

  res = send_request_sync (g_io_stream_get_output_stream (conn), DSI_GET_STATUS,
                           0, 0, 0, NULL, cancellable, error);
  if (!res)
  {
    g_object_unref (conn);
    return NULL;
  }

  res = read_reply_sync (g_io_stream_get_input_stream (conn), &dsi_header,
                         &data, cancellable, error);
  if (!res)
  {
    g_object_unref (conn);
    return NULL;
  }

  g_object_unref (conn);
  
  return g_vfs_afp_reply_new (dsi_header.errorCode, data,
                              dsi_header.totalDataLength, TRUE);
}
Beispiel #3
0
gboolean
g_vfs_afp_connection_send_command_sync (GVfsAfpConnection *afp_connection,
                                        GVfsAfpCommand    *afp_command,
                                        GCancellable      *cancellable,
                                        GError            **error)
{
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;
  
  DsiCommand dsi_command;
  guint16 req_id;
  guint32 writeOffset;

  /* set dsi_command */
  switch (afp_command->type)
  {
    case AFP_COMMAND_WRITE:
      writeOffset = 8;
      dsi_command = DSI_WRITE;
      break;
    case AFP_COMMAND_WRITE_EXT:
      writeOffset = 20;
      dsi_command = DSI_WRITE;
      break;

    default:
      writeOffset = 0;
      dsi_command = DSI_COMMAND;
      break;
  }

  req_id = get_request_id (afp_connection);
  return send_request_sync (g_io_stream_get_output_stream (priv->conn),
                            dsi_command, req_id, writeOffset,
                            g_vfs_afp_command_get_size (afp_command),
                            g_vfs_afp_command_get_data (afp_command),
                            cancellable, error);
}
Beispiel #4
0
gboolean
g_vfs_afp_connection_open (GVfsAfpConnection *afp_connection,
                           GCancellable      *cancellable,
                           GError            **error)
{
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;

  GSocketClient *client;

  guint16 req_id;
  gboolean res;
  char *reply;
  DSIHeader dsi_header;
  guint pos;

  client = g_socket_client_new ();
  priv->conn = G_IO_STREAM (g_socket_client_connect (client, priv->addr, cancellable, error));
  g_object_unref (client);

  if (!priv->conn)
    return FALSE;

  req_id = get_request_id (afp_connection);
  res = send_request_sync (g_io_stream_get_output_stream (priv->conn),
                           DSI_OPEN_SESSION, req_id, 0,  0, NULL,
                           cancellable, error);
  if (!res)
    return FALSE;

  res = read_reply_sync (g_io_stream_get_input_stream (priv->conn),
                         &dsi_header, &reply, cancellable, error);
  if (!res)
    return FALSE;

  pos = 0;
  while ((dsi_header.totalDataLength - pos) > 2)
  {
    guint8 optionType;
    guint8 optionLength;

    optionType = reply[pos++];
    optionLength = reply[pos++];

    switch (optionType)
    {
      
      case 0x00:
        if (optionLength == 4 && (dsi_header.totalDataLength - pos) >= 4)
          priv->kRequestQuanta = GUINT32_FROM_BE (*(guint32 *)(reply + pos));

        break;
        
      case 0x02:
        if (optionLength == 4 && (dsi_header.totalDataLength - pos) >= 4)
         priv->kServerReplayCacheSize = GUINT32_FROM_BE (*(guint32 *)(reply + pos));

        break;
      

      default:
        g_debug ("Unknown DSI option\n");
    }

    pos += optionLength;
  }
  g_free (reply);

  return TRUE;
}
Beispiel #5
0
static gpointer
open_thread_func (gpointer user_data)
{
  SyncData *data = user_data;
  GVfsAfpConnection *conn = data->conn;
  GVfsAfpConnectionPrivate *priv = conn->priv;

  GSocketClient *client;

  guint16 req_id;
  gboolean res = FALSE;
  char *reply;
  DSIHeader dsi_header;
  guint pos;

  client = g_socket_client_new ();
  priv->stream = G_IO_STREAM (g_socket_client_connect (client, priv->addr, data->cancellable,
                                                       data->error));
  g_object_unref (client);

  if (!priv->stream)
    goto out;

  req_id = get_request_id (conn);
  res = send_request_sync (g_io_stream_get_output_stream (priv->stream),
                           DSI_OPEN_SESSION, req_id, 0,  0, NULL,
                           data->cancellable, data->error);
  if (!res)
    goto out;

  res = read_reply_sync (g_io_stream_get_input_stream (priv->stream),
                         &dsi_header, &reply, data->cancellable, data->error);
  if (!res)
    goto out;

  pos = 0;
  while ((dsi_header.totalDataLength - pos) > 2)
  {
    guint8 optionType;
    guint8 optionLength;

    optionType = reply[pos++];
    optionLength = reply[pos++];

    switch (optionType)
    {
      
      case 0x00:
        if (optionLength == 4 && (dsi_header.totalDataLength - pos) >= 4)
          priv->kRequestQuanta = GUINT32_FROM_BE (*(guint32 *)(reply + pos));

        break;
        
      case 0x02:
        if (optionLength == 4 && (dsi_header.totalDataLength - pos) >= 4)
         priv->kServerReplayCacheSize = GUINT32_FROM_BE (*(guint32 *)(reply + pos));

        break;
      

      default:
        g_debug ("Unknown DSI option\n");
    }

    pos += optionLength;
  }
  g_free (reply);

out:
  if (res)
    g_atomic_int_set (&priv->atomic_state, STATE_CONNECTED);
  
  /* Signal sync call thread */
  data->res = res;
  sync_data_signal (data);

  /* Return from thread on failure */
  if (!res)
  {
    g_clear_object (&priv->stream);
    return NULL;
  }
  
  /* Create MainLoop */
  priv->worker_context = g_main_context_new ();
  priv->worker_loop = g_main_loop_new (priv->worker_context, TRUE);

  read_reply (conn);
  
  /* Run mainloop */
  g_main_loop_run (priv->worker_loop);

  return NULL;
}
Beispiel #6
0
static void
close_connection (GVfsAfpConnection *conn)
{
  GVfsAfpConnectionPrivate *priv = conn->priv;
  
  guint16 req_id;
  gboolean res;
  GError *err = NULL;

  GQueue *request_queue;
  GSList *pending_closes, *siter;
  GHashTable *request_hash;
  GHashTableIter iter;
  RequestData *req_data;

  /* Take lock */
  g_mutex_lock (&priv->mutex);

  /* Set closed flag */
  g_atomic_int_set (&priv->atomic_state, STATE_CLOSED);

  request_queue = priv->request_queue;
  priv->request_queue = NULL;

  request_hash = priv->request_hash;
  priv->request_hash = NULL;
  
  pending_closes = priv->pending_closes;
  priv->pending_closes = NULL;

  /* Release lock */
  g_mutex_unlock (&priv->mutex);
  
  /* close DSI session */
  req_id = get_request_id (conn);
  res = send_request_sync (g_io_stream_get_output_stream (priv->stream),
                           DSI_CLOSE_SESSION, req_id, 0, 0, NULL,
                           NULL, &err);
  if (!res)
    g_io_stream_close (priv->stream, NULL, NULL);
  else
    res = g_io_stream_close (priv->stream, NULL, &err);
  
  g_clear_object (&priv->stream);

#define REQUEST_DATA_CLOSED(request_data) { \
  g_simple_async_result_set_from_error (req_data->simple, \
  g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CLOSED, "Connection was closed")); \
  \
  g_simple_async_result_complete_in_idle (req_data->simple); \
  free_request_data (req_data); \
}

  while ((req_data = g_queue_pop_head (request_queue)))
  {
    REQUEST_DATA_CLOSED (req_data);
  }

  g_hash_table_iter_init (&iter, request_hash);
  while (g_hash_table_iter_next (&iter, NULL, (void **)&req_data))
  {
    REQUEST_DATA_CLOSED (req_data);
  }
  
#undef REQUEST_DATA_CLOSED

  /* quit main_loop */
  g_main_loop_quit (priv->worker_loop);
  g_main_loop_unref (priv->worker_loop);
  g_main_context_unref (priv->worker_context);
  
  for (siter = pending_closes; siter != NULL; siter = siter->next)
  {
    SyncData *close_data = siter->data;

    close_data->res = TRUE;
    sync_data_signal (close_data);
  }
  g_slist_free (pending_closes);
}