예제 #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;
}
예제 #2
0
struct PP_Var nspawn_send_request(struct PP_Var req_var) {
  /*
   * naclprocess.js is required in order send requests to JavaScript.
   * If NACL_PROCESS is not set in the environment then we assume it is
   * not present and exit early. Without this check we would block forever
   * waiting for a response for the JavaScript side.
   *
   * Only check this once per process, as some programs (emacs)
   * engage in manipulation of the environment that may not be safely
   * read at all times.
   */
  static int checked_for_nacl_process = 0;
  if (!checked_for_nacl_process) {
    const char* naclprocess = getenv("NACL_PROCESS");
    if (naclprocess == NULL) {
      fprintf(stderr, "nspawn_send_request called without NACL_PROCESS set\n");
      return PP_MakeNull();
    }
    checked_for_nacl_process = 1;
  }

  int64_t id = get_request_id();
  char req_id[64];
  sprintf(req_id, "%lld", id);
  nspawn_dict_setstring(req_var, "id", req_id);

  struct NaClSpawnReply reply;
  pthread_mutex_init(&reply.mu, NULL);
  pthread_cond_init(&reply.cond, NULL);
  PSEventRegisterMessageHandler(req_id, &handle_reply, &reply);

  PSInterfaceMessaging()->PostMessage(PSGetInstanceId(), req_var);
  nspawn_var_release(req_var);

  pthread_mutex_lock(&reply.mu);
  /*
   * Wait for response for JavaScript.  This can block for an unbounded amount
   * of time (e.g. waiting for a response to waitpid).
   */
  int error = pthread_cond_wait(&reply.cond, &reply.mu);
  pthread_mutex_unlock(&reply.mu);

  pthread_cond_destroy(&reply.cond);
  pthread_mutex_destroy(&reply.mu);

  PSEventRegisterMessageHandler(req_id, NULL, &reply);

  if (error != 0) {
    fprintf(stderr, "nspawn_send_request: pthread_cond_timedwait: %s\n",
          strerror(error));
    return PP_MakeNull();
  }

  return reply.result_var;
}
예제 #3
0
static int rcp_recv()
{
	int res;
	int len;
	int received;

	unsigned char buffer[RCP_MAX_PACKET_LEN];

	res = recv(con.control_socket, buffer, TPKT_HEADER_LENGTH, 0);
	if (res == -1)
		goto error;

	len = ntohs(*(unsigned short*)(buffer+2));
	len -= TPKT_HEADER_LENGTH;

	received = 0;
	while (received < len)
	{
		res = recv(con.control_socket, buffer+received, len-received, 0);
		if (res == -1)
			goto error;
		TL_DEBUG("%d bytes received", res);
		received += res;
	}

	tlog_hex(TLOG_DEBUG, "received", buffer, received);

	int request_id = get_request_id(buffer);

	rcp_packet* hdr = &resp[request_id];

	read_rcp_header(buffer, hdr);

	memcpy(hdr->payload, buffer+RCP_HEADER_LENGTH, hdr->payload_length);

	return request_id;

error:
	TL_ERROR("rcp_recv: %d - %s\n", errno, strerror(errno));
	return -1;
}
예제 #4
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);
}
예제 #5
0
파일: pdu.cpp 프로젝트: azraelly/knetwork
    get_vb(bad, get_error_index() -1); // not zero based??
    const char *pmsg =   Snmp::error_string(get_error_status());
    const char *id =   bad.to_string_oid();
    const char *val =  bad.to_string_value();
    const int HDR_SZ = 100;

    if (!output_) {
      int size = ACE_OS::strlen(pmsg) + ACE_OS::strlen(id) +
           ACE_OS::strlen(val);
      ACE_NEW_RETURN(output_, char[size + HDR_SZ], "");
    }

    ACE_OS::sprintf(output_,
                    "FAIL PDU REPORT: pdu id: %lu vb cnt: %d vb idx: %d\n"
                    "                 msg: %s vb oid: %s value: %s\n",
                    get_request_id(), n_vbs, get_error_index(),
                    pmsg, id, val);

    return output_;
}

//=====================[ set the error status ]==========================
// friend
void set_error_status( Pdu *pdu, const int status)
{
   if (pdu)
     pdu->error_status_ = status;
}

//=====================[ return the error index ]========================
int Pdu::get_error_index() const
예제 #6
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;
}
예제 #7
0
static void
send_request (GVfsAfpConnection *afp_connection)
{
  GVfsAfpConnectionPrivate *priv = afp_connection->priv;

  RequestData *req_data;
  guint32 writeOffset;
  guint8 dsi_command;

  while ((req_data = g_queue_peek_head (priv->request_queue)))
  {
    if (req_data->cancellable && g_cancellable_is_cancelled (req_data->cancellable))
    {
      if (req_data->simple)
      {
        GError *err = NULL;

        g_cancellable_set_error_if_cancelled (req_data->cancellable, &err);
        g_simple_async_result_take_error (req_data->simple, err);
        g_simple_async_result_complete (req_data->simple);
      }
      remove_first (priv->request_queue);
    }
    else
      break;
  }

  if (!req_data) {
    priv->send_loop_running = FALSE;
    return;
  }

  switch (req_data->type)
  {
    case REQUEST_TYPE_TICKLE:
      priv->write_dsi_header.flags = 0x00;
      priv->write_dsi_header.command = DSI_TICKLE;
      priv->write_dsi_header.requestID = GUINT16_TO_BE (get_request_id (afp_connection));
      priv->write_dsi_header.writeOffset = 0;
      priv->write_dsi_header.totalDataLength = 0;
      priv->write_dsi_header.reserved = 0;
      break;

    case REQUEST_TYPE_COMMAND:
    {
      gsize size;
      
      switch (req_data->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;
      }

      priv->write_dsi_header.flags = 0x00;
      priv->write_dsi_header.command = dsi_command;
      priv->write_dsi_header.requestID = GUINT16_TO_BE (get_request_id (afp_connection));
      priv->write_dsi_header.writeOffset = GUINT32_TO_BE (writeOffset);

      /* totalDataLength */
      size = g_vfs_afp_command_get_size (req_data->command);
      if (dsi_command == DSI_WRITE && req_data->command->buf)
        size += req_data->command->buf_size;
      priv->write_dsi_header.totalDataLength = GUINT32_TO_BE (size);
      
      priv->write_dsi_header.reserved = 0;
      break;
    }

    default:
      g_assert_not_reached ();
  }


  write_all_async (g_io_stream_get_output_stream (priv->conn),
                   &priv->write_dsi_header, sizeof (DSIHeader), 0,
                   NULL, write_dsi_header_cb, afp_connection);
}
예제 #8
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;
}
예제 #9
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);
}