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; }
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; }
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; }
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); }
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
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; }
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); }
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; }
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); }