/* meta key for storing RTMP* at connection */
#define CURL_META_RTMP_CONN "meta:proto:rtmp:conn"
-
-static CURLcode rtmp_setup_connection(struct Curl_easy *data,
- struct connectdata *conn);
-static CURLcode rtmp_do(struct Curl_easy *data, bool *done);
-static CURLcode rtmp_done(struct Curl_easy *data, CURLcode, bool premature);
-static CURLcode rtmp_connect(struct Curl_easy *data, bool *done);
-static CURLcode rtmp_disconnect(struct Curl_easy *data,
- struct connectdata *conn, bool dead);
-
static Curl_recv rtmp_recv;
static Curl_send rtmp_send;
-/*
- * RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu/
- */
-
-const struct Curl_handler Curl_handler_rtmp = {
- "rtmp", /* scheme */
- rtmp_setup_connection, /* setup_connection */
- rtmp_do, /* do_it */
- rtmp_done, /* done */
- ZERO_NULL, /* do_more */
- rtmp_connect, /* connect_it */
- ZERO_NULL, /* connecting */
- ZERO_NULL, /* doing */
- ZERO_NULL, /* proto_pollset */
- ZERO_NULL, /* doing_pollset */
- ZERO_NULL, /* domore_pollset */
- ZERO_NULL, /* perform_pollset */
- rtmp_disconnect, /* disconnect */
- ZERO_NULL, /* write_resp */
- ZERO_NULL, /* write_resp_hd */
- ZERO_NULL, /* connection_check */
- ZERO_NULL, /* attach connection */
- ZERO_NULL, /* follow */
- PORT_RTMP, /* defport */
- CURLPROTO_RTMP, /* protocol */
- CURLPROTO_RTMP, /* family */
- PROTOPT_NONE /* flags */
-};
-
-const struct Curl_handler Curl_handler_rtmpt = {
- "rtmpt", /* scheme */
- rtmp_setup_connection, /* setup_connection */
- rtmp_do, /* do_it */
- rtmp_done, /* done */
- ZERO_NULL, /* do_more */
- rtmp_connect, /* connect_it */
- ZERO_NULL, /* connecting */
- ZERO_NULL, /* doing */
- ZERO_NULL, /* proto_pollset */
- ZERO_NULL, /* doing_pollset */
- ZERO_NULL, /* domore_pollset */
- ZERO_NULL, /* perform_pollset */
- rtmp_disconnect, /* disconnect */
- ZERO_NULL, /* write_resp */
- ZERO_NULL, /* write_resp_hd */
- ZERO_NULL, /* connection_check */
- ZERO_NULL, /* attach connection */
- ZERO_NULL, /* follow */
- PORT_RTMPT, /* defport */
- CURLPROTO_RTMPT, /* protocol */
- CURLPROTO_RTMPT, /* family */
- PROTOPT_NONE /* flags */
-};
-
-const struct Curl_handler Curl_handler_rtmpe = {
- "rtmpe", /* scheme */
- rtmp_setup_connection, /* setup_connection */
- rtmp_do, /* do_it */
- rtmp_done, /* done */
- ZERO_NULL, /* do_more */
- rtmp_connect, /* connect_it */
- ZERO_NULL, /* connecting */
- ZERO_NULL, /* doing */
- ZERO_NULL, /* proto_pollset */
- ZERO_NULL, /* doing_pollset */
- ZERO_NULL, /* domore_pollset */
- ZERO_NULL, /* perform_pollset */
- rtmp_disconnect, /* disconnect */
- ZERO_NULL, /* write_resp */
- ZERO_NULL, /* write_resp_hd */
- ZERO_NULL, /* connection_check */
- ZERO_NULL, /* attach connection */
- ZERO_NULL, /* follow */
- PORT_RTMP, /* defport */
- CURLPROTO_RTMPE, /* protocol */
- CURLPROTO_RTMPE, /* family */
- PROTOPT_NONE /* flags */
-};
-
-const struct Curl_handler Curl_handler_rtmpte = {
- "rtmpte", /* scheme */
- rtmp_setup_connection, /* setup_connection */
- rtmp_do, /* do_it */
- rtmp_done, /* done */
- ZERO_NULL, /* do_more */
- rtmp_connect, /* connect_it */
- ZERO_NULL, /* connecting */
- ZERO_NULL, /* doing */
- ZERO_NULL, /* proto_pollset */
- ZERO_NULL, /* doing_pollset */
- ZERO_NULL, /* domore_pollset */
- ZERO_NULL, /* perform_pollset */
- rtmp_disconnect, /* disconnect */
- ZERO_NULL, /* write_resp */
- ZERO_NULL, /* write_resp_hd */
- ZERO_NULL, /* connection_check */
- ZERO_NULL, /* attach connection */
- ZERO_NULL, /* follow */
- PORT_RTMPT, /* defport */
- CURLPROTO_RTMPTE, /* protocol */
- CURLPROTO_RTMPTE, /* family */
- PROTOPT_NONE /* flags */
-};
-
-const struct Curl_handler Curl_handler_rtmps = {
- "rtmps", /* scheme */
- rtmp_setup_connection, /* setup_connection */
- rtmp_do, /* do_it */
- rtmp_done, /* done */
- ZERO_NULL, /* do_more */
- rtmp_connect, /* connect_it */
- ZERO_NULL, /* connecting */
- ZERO_NULL, /* doing */
- ZERO_NULL, /* proto_pollset */
- ZERO_NULL, /* doing_pollset */
- ZERO_NULL, /* domore_pollset */
- ZERO_NULL, /* perform_pollset */
- rtmp_disconnect, /* disconnect */
- ZERO_NULL, /* write_resp */
- ZERO_NULL, /* write_resp_hd */
- ZERO_NULL, /* connection_check */
- ZERO_NULL, /* attach connection */
- ZERO_NULL, /* follow */
- PORT_RTMPS, /* defport */
- CURLPROTO_RTMPS, /* protocol */
- CURLPROTO_RTMP, /* family */
- PROTOPT_NONE /* flags */
-};
-
-const struct Curl_handler Curl_handler_rtmpts = {
- "rtmpts", /* scheme */
- rtmp_setup_connection, /* setup_connection */
- rtmp_do, /* do_it */
- rtmp_done, /* done */
- ZERO_NULL, /* do_more */
- rtmp_connect, /* connect_it */
- ZERO_NULL, /* connecting */
- ZERO_NULL, /* doing */
- ZERO_NULL, /* proto_pollset */
- ZERO_NULL, /* doing_pollset */
- ZERO_NULL, /* domore_pollset */
- ZERO_NULL, /* perform_pollset */
- rtmp_disconnect, /* disconnect */
- ZERO_NULL, /* write_resp */
- ZERO_NULL, /* write_resp_hd */
- ZERO_NULL, /* connection_check */
- ZERO_NULL, /* attach connection */
- ZERO_NULL, /* follow */
- PORT_RTMPS, /* defport */
- CURLPROTO_RTMPTS, /* protocol */
- CURLPROTO_RTMPT, /* family */
- PROTOPT_NONE /* flags */
-};
-
static void rtmp_conn_dtor(void *key, size_t klen, void *entry)
{
RTMP *r = entry;
suff);
}
+/*
+ * RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu/
+ */
+
+const struct Curl_handler Curl_handler_rtmp = {
+ "rtmp", /* scheme */
+ rtmp_setup_connection, /* setup_connection */
+ rtmp_do, /* do_it */
+ rtmp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtmp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_pollset */
+ ZERO_NULL, /* doing_pollset */
+ ZERO_NULL, /* domore_pollset */
+ ZERO_NULL, /* perform_pollset */
+ rtmp_disconnect, /* disconnect */
+ ZERO_NULL, /* write_resp */
+ ZERO_NULL, /* write_resp_hd */
+ ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ ZERO_NULL, /* follow */
+ PORT_RTMP, /* defport */
+ CURLPROTO_RTMP, /* protocol */
+ CURLPROTO_RTMP, /* family */
+ PROTOPT_NONE /* flags */
+};
+
+const struct Curl_handler Curl_handler_rtmpt = {
+ "rtmpt", /* scheme */
+ rtmp_setup_connection, /* setup_connection */
+ rtmp_do, /* do_it */
+ rtmp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtmp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_pollset */
+ ZERO_NULL, /* doing_pollset */
+ ZERO_NULL, /* domore_pollset */
+ ZERO_NULL, /* perform_pollset */
+ rtmp_disconnect, /* disconnect */
+ ZERO_NULL, /* write_resp */
+ ZERO_NULL, /* write_resp_hd */
+ ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ ZERO_NULL, /* follow */
+ PORT_RTMPT, /* defport */
+ CURLPROTO_RTMPT, /* protocol */
+ CURLPROTO_RTMPT, /* family */
+ PROTOPT_NONE /* flags */
+};
+
+const struct Curl_handler Curl_handler_rtmpe = {
+ "rtmpe", /* scheme */
+ rtmp_setup_connection, /* setup_connection */
+ rtmp_do, /* do_it */
+ rtmp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtmp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_pollset */
+ ZERO_NULL, /* doing_pollset */
+ ZERO_NULL, /* domore_pollset */
+ ZERO_NULL, /* perform_pollset */
+ rtmp_disconnect, /* disconnect */
+ ZERO_NULL, /* write_resp */
+ ZERO_NULL, /* write_resp_hd */
+ ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ ZERO_NULL, /* follow */
+ PORT_RTMP, /* defport */
+ CURLPROTO_RTMPE, /* protocol */
+ CURLPROTO_RTMPE, /* family */
+ PROTOPT_NONE /* flags */
+};
+
+const struct Curl_handler Curl_handler_rtmpte = {
+ "rtmpte", /* scheme */
+ rtmp_setup_connection, /* setup_connection */
+ rtmp_do, /* do_it */
+ rtmp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtmp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_pollset */
+ ZERO_NULL, /* doing_pollset */
+ ZERO_NULL, /* domore_pollset */
+ ZERO_NULL, /* perform_pollset */
+ rtmp_disconnect, /* disconnect */
+ ZERO_NULL, /* write_resp */
+ ZERO_NULL, /* write_resp_hd */
+ ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ ZERO_NULL, /* follow */
+ PORT_RTMPT, /* defport */
+ CURLPROTO_RTMPTE, /* protocol */
+ CURLPROTO_RTMPTE, /* family */
+ PROTOPT_NONE /* flags */
+};
+
+const struct Curl_handler Curl_handler_rtmps = {
+ "rtmps", /* scheme */
+ rtmp_setup_connection, /* setup_connection */
+ rtmp_do, /* do_it */
+ rtmp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtmp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_pollset */
+ ZERO_NULL, /* doing_pollset */
+ ZERO_NULL, /* domore_pollset */
+ ZERO_NULL, /* perform_pollset */
+ rtmp_disconnect, /* disconnect */
+ ZERO_NULL, /* write_resp */
+ ZERO_NULL, /* write_resp_hd */
+ ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ ZERO_NULL, /* follow */
+ PORT_RTMPS, /* defport */
+ CURLPROTO_RTMPS, /* protocol */
+ CURLPROTO_RTMP, /* family */
+ PROTOPT_NONE /* flags */
+};
+
+const struct Curl_handler Curl_handler_rtmpts = {
+ "rtmpts", /* scheme */
+ rtmp_setup_connection, /* setup_connection */
+ rtmp_do, /* do_it */
+ rtmp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtmp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_pollset */
+ ZERO_NULL, /* doing_pollset */
+ ZERO_NULL, /* domore_pollset */
+ ZERO_NULL, /* perform_pollset */
+ rtmp_disconnect, /* disconnect */
+ ZERO_NULL, /* write_resp */
+ ZERO_NULL, /* write_resp_hd */
+ ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ ZERO_NULL, /* follow */
+ PORT_RTMPS, /* defport */
+ CURLPROTO_RTMPTS, /* protocol */
+ CURLPROTO_RTMPT, /* family */
+ PROTOPT_NONE /* flags */
+};
+
#endif /* USE_LIBRTMP */
#define LDAP_OPT_OFF ((void *)(size_t)0)
#endif
-static CURLcode ldap_do(struct Curl_easy *data, bool *done);
-
-/*
- * LDAP protocol handler.
- */
-const struct Curl_handler Curl_handler_ldap = {
- "ldap", /* scheme */
- ZERO_NULL, /* setup_connection */
- ldap_do, /* do_it */
- ZERO_NULL, /* done */
- ZERO_NULL, /* do_more */
- ZERO_NULL, /* connect_it */
- ZERO_NULL, /* connecting */
- ZERO_NULL, /* doing */
- ZERO_NULL, /* proto_pollset */
- ZERO_NULL, /* doing_pollset */
- ZERO_NULL, /* domore_pollset */
- ZERO_NULL, /* perform_pollset */
- ZERO_NULL, /* disconnect */
- ZERO_NULL, /* write_resp */
- ZERO_NULL, /* write_resp_hd */
- ZERO_NULL, /* connection_check */
- ZERO_NULL, /* attach connection */
- ZERO_NULL, /* follow */
- PORT_LDAP, /* defport */
- CURLPROTO_LDAP, /* protocol */
- CURLPROTO_LDAP, /* family */
- PROTOPT_SSL_REUSE /* flags */
-};
-
-#ifdef HAVE_LDAP_SSL
-/*
- * LDAPS protocol handler.
- */
-const struct Curl_handler Curl_handler_ldaps = {
- "ldaps", /* scheme */
- ZERO_NULL, /* setup_connection */
- ldap_do, /* do_it */
- ZERO_NULL, /* done */
- ZERO_NULL, /* do_more */
- ZERO_NULL, /* connect_it */
- ZERO_NULL, /* connecting */
- ZERO_NULL, /* doing */
- ZERO_NULL, /* proto_pollset */
- ZERO_NULL, /* doing_pollset */
- ZERO_NULL, /* domore_pollset */
- ZERO_NULL, /* perform_pollset */
- ZERO_NULL, /* disconnect */
- ZERO_NULL, /* write_resp */
- ZERO_NULL, /* write_resp_hd */
- ZERO_NULL, /* connection_check */
- ZERO_NULL, /* attach connection */
- ZERO_NULL, /* follow */
- PORT_LDAPS, /* defport */
- CURLPROTO_LDAPS, /* protocol */
- CURLPROTO_LDAP, /* family */
- PROTOPT_SSL /* flags */
-};
-#endif
-
#ifdef USE_WIN32_LDAP
#ifdef USE_WINDOWS_SSPI
#endif
}
+/*
+ * LDAP protocol handler.
+ */
+const struct Curl_handler Curl_handler_ldap = {
+ "ldap", /* scheme */
+ ZERO_NULL, /* setup_connection */
+ ldap_do, /* do_it */
+ ZERO_NULL, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_pollset */
+ ZERO_NULL, /* doing_pollset */
+ ZERO_NULL, /* domore_pollset */
+ ZERO_NULL, /* perform_pollset */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* write_resp */
+ ZERO_NULL, /* write_resp_hd */
+ ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ ZERO_NULL, /* follow */
+ PORT_LDAP, /* defport */
+ CURLPROTO_LDAP, /* protocol */
+ CURLPROTO_LDAP, /* family */
+ PROTOPT_SSL_REUSE /* flags */
+};
+
+#ifdef HAVE_LDAP_SSL
+/*
+ * LDAPS protocol handler.
+ */
+const struct Curl_handler Curl_handler_ldaps = {
+ "ldaps", /* scheme */
+ ZERO_NULL, /* setup_connection */
+ ldap_do, /* do_it */
+ ZERO_NULL, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_pollset */
+ ZERO_NULL, /* doing_pollset */
+ ZERO_NULL, /* domore_pollset */
+ ZERO_NULL, /* perform_pollset */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* write_resp */
+ ZERO_NULL, /* write_resp_hd */
+ ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ ZERO_NULL, /* follow */
+ PORT_LDAPS, /* defport */
+ CURLPROTO_LDAPS, /* protocol */
+ CURLPROTO_LDAP, /* family */
+ PROTOPT_SSL /* flags */
+};
+#endif
+
#if defined(__GNUC__) && defined(__APPLE__)
#pragma GCC diagnostic pop
#endif
LDAP **ld);
#endif
-static CURLcode oldap_setup_connection(struct Curl_easy *data,
- struct connectdata *conn);
-static CURLcode oldap_do(struct Curl_easy *data, bool *done);
-static CURLcode oldap_done(struct Curl_easy *data, CURLcode, bool);
-static CURLcode oldap_connect(struct Curl_easy *data, bool *done);
-static CURLcode oldap_connecting(struct Curl_easy *data, bool *done);
-static CURLcode oldap_disconnect(struct Curl_easy *data,
- struct connectdata *conn, bool dead);
-
-static CURLcode oldap_perform_auth(struct Curl_easy *data, const char *mech,
- const struct bufref *initresp);
-static CURLcode oldap_continue_auth(struct Curl_easy *data, const char *mech,
- const struct bufref *resp);
-static CURLcode oldap_cancel_auth(struct Curl_easy *data, const char *mech);
-static CURLcode oldap_get_message(struct Curl_easy *data, struct bufref *out);
-
static Curl_recv oldap_recv;
-/*
- * LDAP protocol handler.
- */
-const struct Curl_handler Curl_handler_ldap = {
- "ldap", /* scheme */
- oldap_setup_connection, /* setup_connection */
- oldap_do, /* do_it */
- oldap_done, /* done */
- ZERO_NULL, /* do_more */
- oldap_connect, /* connect_it */
- oldap_connecting, /* connecting */
- ZERO_NULL, /* doing */
- ZERO_NULL, /* proto_pollset */
- ZERO_NULL, /* doing_pollset */
- ZERO_NULL, /* domore_pollset */
- ZERO_NULL, /* perform_pollset */
- oldap_disconnect, /* disconnect */
- ZERO_NULL, /* write_resp */
- ZERO_NULL, /* write_resp_hd */
- ZERO_NULL, /* connection_check */
- ZERO_NULL, /* attach connection */
- ZERO_NULL, /* follow */
- PORT_LDAP, /* defport */
- CURLPROTO_LDAP, /* protocol */
- CURLPROTO_LDAP, /* family */
- PROTOPT_SSL_REUSE | /* flags */
- PROTOPT_CONN_REUSE
-};
-
-#ifdef USE_SSL
-/*
- * LDAPS protocol handler.
- */
-const struct Curl_handler Curl_handler_ldaps = {
- "ldaps", /* scheme */
- oldap_setup_connection, /* setup_connection */
- oldap_do, /* do_it */
- oldap_done, /* done */
- ZERO_NULL, /* do_more */
- oldap_connect, /* connect_it */
- oldap_connecting, /* connecting */
- ZERO_NULL, /* doing */
- ZERO_NULL, /* proto_pollset */
- ZERO_NULL, /* doing_pollset */
- ZERO_NULL, /* domore_pollset */
- ZERO_NULL, /* perform_pollset */
- oldap_disconnect, /* disconnect */
- ZERO_NULL, /* write_resp */
- ZERO_NULL, /* write_resp_hd */
- ZERO_NULL, /* connection_check */
- ZERO_NULL, /* attach connection */
- ZERO_NULL, /* follow */
- PORT_LDAPS, /* defport */
- CURLPROTO_LDAPS, /* protocol */
- CURLPROTO_LDAP, /* family */
- PROTOPT_SSL | /* flags */
- PROTOPT_CONN_REUSE
-};
-#endif
-
-/* SASL parameters for the ldap protocol */
-static const struct SASLproto saslldap = {
- "ldap", /* The service name */
- oldap_perform_auth, /* Send authentication command */
- oldap_continue_auth, /* Send authentication continuation */
- oldap_cancel_auth, /* Send authentication cancellation */
- oldap_get_message, /* Get SASL response message */
- 0, /* Maximum initial response length (no max) */
- LDAP_SASL_BIND_IN_PROGRESS, /* Code received when continuation is expected */
- LDAP_SUCCESS, /* Code to receive upon authentication success */
- SASL_AUTH_NONE, /* Default mechanisms */
- 0 /* Configuration flags */
-};
-
struct ldapconninfo {
struct SASL sasl; /* SASL-related parameters */
LDAP *ld; /* Openldap connection handle. */
curlx_free(li);
}
+/* SASL parameters for the ldap protocol */
+static const struct SASLproto saslldap = {
+ "ldap", /* The service name */
+ oldap_perform_auth, /* Send authentication command */
+ oldap_continue_auth, /* Send authentication continuation */
+ oldap_cancel_auth, /* Send authentication cancellation */
+ oldap_get_message, /* Get SASL response message */
+ 0, /* Maximum initial response length (no max) */
+ LDAP_SASL_BIND_IN_PROGRESS, /* Code received when continuation is expected */
+ LDAP_SUCCESS, /* Code to receive upon authentication success */
+ SASL_AUTH_NONE, /* Default mechanisms */
+ 0 /* Configuration flags */
+};
+
static CURLcode oldap_connect(struct Curl_easy *data, bool *done)
{
struct connectdata *conn = data->conn;
curl_msnprintf(buf, bufsz, "OpenLDAP");
}
+/*
+ * LDAP protocol handler.
+ */
+const struct Curl_handler Curl_handler_ldap = {
+ "ldap", /* scheme */
+ oldap_setup_connection, /* setup_connection */
+ oldap_do, /* do_it */
+ oldap_done, /* done */
+ ZERO_NULL, /* do_more */
+ oldap_connect, /* connect_it */
+ oldap_connecting, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_pollset */
+ ZERO_NULL, /* doing_pollset */
+ ZERO_NULL, /* domore_pollset */
+ ZERO_NULL, /* perform_pollset */
+ oldap_disconnect, /* disconnect */
+ ZERO_NULL, /* write_resp */
+ ZERO_NULL, /* write_resp_hd */
+ ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ ZERO_NULL, /* follow */
+ PORT_LDAP, /* defport */
+ CURLPROTO_LDAP, /* protocol */
+ CURLPROTO_LDAP, /* family */
+ PROTOPT_SSL_REUSE | /* flags */
+ PROTOPT_CONN_REUSE
+};
+
+#ifdef USE_SSL
+/*
+ * LDAPS protocol handler.
+ */
+const struct Curl_handler Curl_handler_ldaps = {
+ "ldaps", /* scheme */
+ oldap_setup_connection, /* setup_connection */
+ oldap_do, /* do_it */
+ oldap_done, /* done */
+ ZERO_NULL, /* do_more */
+ oldap_connect, /* connect_it */
+ oldap_connecting, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_pollset */
+ ZERO_NULL, /* doing_pollset */
+ ZERO_NULL, /* domore_pollset */
+ ZERO_NULL, /* perform_pollset */
+ oldap_disconnect, /* disconnect */
+ ZERO_NULL, /* write_resp */
+ ZERO_NULL, /* write_resp_hd */
+ ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ ZERO_NULL, /* follow */
+ PORT_LDAPS, /* defport */
+ CURLPROTO_LDAPS, /* protocol */
+ CURLPROTO_LDAP, /* family */
+ PROTOPT_SSL | /* flags */
+ PROTOPT_CONN_REUSE
+};
+#endif
+
#endif /* !CURL_DISABLE_LDAP && USE_OPENLDAP */
#define RTP_PKT_LENGTH(p) ((((unsigned int)((unsigned char)((p)[2]))) << 8) | \
((unsigned int)((unsigned char)((p)[3]))))
-/* protocol-specific functions set up to be called by the main engine */
-static CURLcode rtsp_do(struct Curl_easy *data, bool *done);
-static CURLcode rtsp_done(struct Curl_easy *data, CURLcode, bool premature);
-static CURLcode rtsp_connect(struct Curl_easy *data, bool *done);
-static CURLcode rtsp_do_pollset(struct Curl_easy *data,
- struct easy_pollset *ps);
-
/*
* Parse and write out an RTSP response.
* @param data the transfer
static CURLcode rtsp_parse_transport(struct Curl_easy *data,
const char *transport);
-/*
- * RTSP handler interface.
- */
-const struct Curl_handler Curl_handler_rtsp = {
- "rtsp", /* scheme */
- rtsp_setup_connection, /* setup_connection */
- rtsp_do, /* do_it */
- rtsp_done, /* done */
- ZERO_NULL, /* do_more */
- rtsp_connect, /* connect_it */
- ZERO_NULL, /* connecting */
- ZERO_NULL, /* doing */
- ZERO_NULL, /* proto_pollset */
- rtsp_do_pollset, /* doing_pollset */
- ZERO_NULL, /* domore_pollset */
- Curl_http_perform_pollset, /* perform_pollset */
- ZERO_NULL, /* disconnect */
- rtsp_rtp_write_resp, /* write_resp */
- rtsp_rtp_write_resp_hd, /* write_resp_hd */
- rtsp_conncheck, /* connection_check */
- ZERO_NULL, /* attach connection */
- Curl_http_follow, /* follow */
- PORT_RTSP, /* defport */
- CURLPROTO_RTSP, /* protocol */
- CURLPROTO_RTSP, /* family */
- PROTOPT_CONN_REUSE /* flags */
-};
-
#define MAX_RTP_BUFFERSIZE 1000000 /* arbitrary */
static void rtsp_easy_dtor(void *key, size_t klen, void *entry)
return CURLE_OK;
}
+/*
+ * RTSP handler interface.
+ */
+const struct Curl_handler Curl_handler_rtsp = {
+ "rtsp", /* scheme */
+ rtsp_setup_connection, /* setup_connection */
+ rtsp_do, /* do_it */
+ rtsp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtsp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_pollset */
+ rtsp_do_pollset, /* doing_pollset */
+ ZERO_NULL, /* domore_pollset */
+ Curl_http_perform_pollset, /* perform_pollset */
+ ZERO_NULL, /* disconnect */
+ rtsp_rtp_write_resp, /* write_resp */
+ rtsp_rtp_write_resp_hd, /* write_resp_hd */
+ rtsp_conncheck, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ Curl_http_follow, /* follow */
+ PORT_RTSP, /* defport */
+ CURLPROTO_RTSP, /* protocol */
+ CURLPROTO_RTSP, /* family */
+ PROTOPT_CONN_REUSE /* flags */
+};
+
#endif /* CURL_DISABLE_RTSP */
#define CURL_SB_PEEK(x) ((*x->subpointer)&0xff)
#define CURL_SB_EOF(x) (x->subpointer >= x->subend) */
-#ifdef CURL_DISABLE_VERBOSE_STRINGS
-#define printoption(a, b, c, d) Curl_nop_stmt
-#endif
-
/* For negotiation compliant to RFC 1143 */
#define CURL_NO 0
#define CURL_YES 1
unsigned char *subpointer, *subend; /* buffer for sub-options */
};
-static CURLcode telrcv(struct Curl_easy *data,
- struct TELNET *tn,
- const unsigned char *inbuf, /* Data received from
- socket */
- ssize_t count); /* Number of bytes
- received */
-
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+#define printoption(a, b, c, d) Curl_nop_stmt
+#else
static void printoption(struct Curl_easy *data,
- const char *direction,
- int cmd, int option);
-#endif
-
-static void send_negotiation(struct Curl_easy *data, int cmd, int option);
-static void set_local_option(struct Curl_easy *data, struct TELNET *tn,
- int option, int newstate);
-static void set_remote_option(struct Curl_easy *data, struct TELNET *tn,
- int option, int newstate);
-
-static void printsub(struct Curl_easy *data,
- int direction, unsigned char *pointer,
- size_t length);
-static CURLcode suboption(struct Curl_easy *data, struct TELNET *tn);
-static void sendsuboption(struct Curl_easy *data,
- struct TELNET *tn, int option);
-
-static CURLcode telnet_do(struct Curl_easy *data, bool *done);
-static CURLcode telnet_done(struct Curl_easy *data,
- CURLcode, bool premature);
-static CURLcode send_telnet_data(struct Curl_easy *data,
- struct TELNET *tn,
- char *buffer, ssize_t nread);
-
-/*
- * TELNET protocol handler.
- */
+ const char *direction, int cmd, int option)
+{
+ if(data->set.verbose) {
+ if(cmd == CURL_IAC) {
+ if(CURL_TELCMD_OK(option))
+ infof(data, "%s IAC %s", direction, CURL_TELCMD(option));
+ else
+ infof(data, "%s IAC %d", direction, option);
+ }
+ else {
+ const char *fmt = (cmd == CURL_WILL) ? "WILL" :
+ (cmd == CURL_WONT) ? "WONT" :
+ (cmd == CURL_DO) ? "DO" :
+ (cmd == CURL_DONT) ? "DONT" : 0;
+ if(fmt) {
+ const char *opt;
+ if(CURL_TELOPT_OK(option))
+ opt = CURL_TELOPT(option);
+ else if(option == CURL_TELOPT_EXOPL)
+ opt = "EXOPL";
+ else
+ opt = NULL;
-const struct Curl_handler Curl_handler_telnet = {
- "telnet", /* scheme */
- ZERO_NULL, /* setup_connection */
- telnet_do, /* do_it */
- telnet_done, /* done */
- ZERO_NULL, /* do_more */
- ZERO_NULL, /* connect_it */
- ZERO_NULL, /* connecting */
- ZERO_NULL, /* doing */
- ZERO_NULL, /* proto_pollset */
- ZERO_NULL, /* doing_pollset */
- ZERO_NULL, /* domore_pollset */
- ZERO_NULL, /* perform_pollset */
- ZERO_NULL, /* disconnect */
- ZERO_NULL, /* write_resp */
- ZERO_NULL, /* write_resp_hd */
- ZERO_NULL, /* connection_check */
- ZERO_NULL, /* attach connection */
- ZERO_NULL, /* follow */
- PORT_TELNET, /* defport */
- CURLPROTO_TELNET, /* protocol */
- CURLPROTO_TELNET, /* family */
- PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
-};
+ if(opt)
+ infof(data, "%s %s %s", direction, fmt, opt);
+ else
+ infof(data, "%s %s %d", direction, fmt, option);
+ }
+ else
+ infof(data, "%s %d %d", direction, cmd, option);
+ }
+ }
+}
+#endif /* CURL_DISABLE_VERBOSE_STRINGS */
static void telnet_easy_dtor(void *key, size_t klen, void *entry)
{
return Curl_meta_set(data, CURL_META_TELNET_EASY, tn, telnet_easy_dtor);
}
-static void telnet_negotiate(struct Curl_easy *data, struct TELNET *tn)
-{
- int i;
-
- for(i = 0; i < CURL_NTELOPTS; i++) {
- if(i == CURL_TELOPT_ECHO)
- continue;
-
- if(tn->us_preferred[i] == CURL_YES)
- set_local_option(data, tn, i, CURL_YES);
-
- if(tn->him_preferred[i] == CURL_YES)
- set_remote_option(data, tn, i, CURL_YES);
- }
-}
-
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
-static void printoption(struct Curl_easy *data,
- const char *direction, int cmd, int option)
-{
- if(data->set.verbose) {
- if(cmd == CURL_IAC) {
- if(CURL_TELCMD_OK(option))
- infof(data, "%s IAC %s", direction, CURL_TELCMD(option));
- else
- infof(data, "%s IAC %d", direction, option);
- }
- else {
- const char *fmt = (cmd == CURL_WILL) ? "WILL" :
- (cmd == CURL_WONT) ? "WONT" :
- (cmd == CURL_DO) ? "DO" :
- (cmd == CURL_DONT) ? "DONT" : 0;
- if(fmt) {
- const char *opt;
- if(CURL_TELOPT_OK(option))
- opt = CURL_TELOPT(option);
- else if(option == CURL_TELOPT_EXOPL)
- opt = "EXOPL";
- else
- opt = NULL;
-
- if(opt)
- infof(data, "%s %s %s", direction, fmt, opt);
- else
- infof(data, "%s %s %d", direction, fmt, option);
- }
- else
- infof(data, "%s %d %d", direction, cmd, option);
- }
- }
-}
-#endif
-
static void send_negotiation(struct Curl_easy *data, int cmd, int option)
{
unsigned char buf[3];
}
}
-static void rec_will(struct Curl_easy *data, struct TELNET *tn, int option)
-{
- switch(tn->him[option]) {
- case CURL_NO:
- if(tn->him_preferred[option] == CURL_YES) {
- tn->him[option] = CURL_YES;
- send_negotiation(data, CURL_DO, option);
- }
- else
- send_negotiation(data, CURL_DONT, option);
-
- break;
-
- case CURL_YES:
- /* Already enabled */
- break;
-
- case CURL_WANTNO:
- switch(tn->himq[option]) {
- case CURL_EMPTY:
- /* Error: DONT answered by WILL */
- tn->him[option] = CURL_NO;
- break;
- case CURL_OPPOSITE:
- /* Error: DONT answered by WILL */
- tn->him[option] = CURL_YES;
- tn->himq[option] = CURL_EMPTY;
- break;
- }
- break;
-
- case CURL_WANTYES:
- switch(tn->himq[option]) {
- case CURL_EMPTY:
- tn->him[option] = CURL_YES;
- break;
- case CURL_OPPOSITE:
- tn->him[option] = CURL_WANTNO;
- tn->himq[option] = CURL_EMPTY;
- send_negotiation(data, CURL_DONT, option);
- break;
- }
- break;
- }
-}
-
-static void rec_wont(struct Curl_easy *data, struct TELNET *tn, int option)
-{
- switch(tn->him[option]) {
- case CURL_NO:
- /* Already disabled */
- break;
-
- case CURL_YES:
- tn->him[option] = CURL_NO;
- send_negotiation(data, CURL_DONT, option);
- break;
-
- case CURL_WANTNO:
- switch(tn->himq[option]) {
- case CURL_EMPTY:
- tn->him[option] = CURL_NO;
- break;
-
- case CURL_OPPOSITE:
- tn->him[option] = CURL_WANTYES;
- tn->himq[option] = CURL_EMPTY;
- send_negotiation(data, CURL_DO, option);
- break;
- }
- break;
-
- case CURL_WANTYES:
- switch(tn->himq[option]) {
- case CURL_EMPTY:
- tn->him[option] = CURL_NO;
- break;
- case CURL_OPPOSITE:
- tn->him[option] = CURL_NO;
- tn->himq[option] = CURL_EMPTY;
- break;
- }
- break;
- }
-}
-
static void set_local_option(struct Curl_easy *data, struct TELNET *tn,
int option, int newstate)
{
}
}
-static void rec_do(struct Curl_easy *data, struct TELNET *tn, int option)
+static void telnet_negotiate(struct Curl_easy *data, struct TELNET *tn)
{
- switch(tn->us[option]) {
+ int i;
+
+ for(i = 0; i < CURL_NTELOPTS; i++) {
+ if(i == CURL_TELOPT_ECHO)
+ continue;
+
+ if(tn->us_preferred[i] == CURL_YES)
+ set_local_option(data, tn, i, CURL_YES);
+
+ if(tn->him_preferred[i] == CURL_YES)
+ set_remote_option(data, tn, i, CURL_YES);
+ }
+}
+
+static void rec_will(struct Curl_easy *data, struct TELNET *tn, int option)
+{
+ switch(tn->him[option]) {
case CURL_NO:
- if(tn->us_preferred[option] == CURL_YES) {
- tn->us[option] = CURL_YES;
- send_negotiation(data, CURL_WILL, option);
- if(tn->subnegotiation[option] == CURL_YES)
- /* transmission of data option */
- sendsuboption(data, tn, option);
- }
- else if(tn->subnegotiation[option] == CURL_YES) {
- /* send information to achieve this option */
- tn->us[option] = CURL_YES;
- send_negotiation(data, CURL_WILL, option);
- sendsuboption(data, tn, option);
+ if(tn->him_preferred[option] == CURL_YES) {
+ tn->him[option] = CURL_YES;
+ send_negotiation(data, CURL_DO, option);
}
else
- send_negotiation(data, CURL_WONT, option);
+ send_negotiation(data, CURL_DONT, option);
+
break;
case CURL_YES:
break;
case CURL_WANTNO:
- switch(tn->usq[option]) {
+ switch(tn->himq[option]) {
case CURL_EMPTY:
/* Error: DONT answered by WILL */
- tn->us[option] = CURL_NO;
+ tn->him[option] = CURL_NO;
break;
case CURL_OPPOSITE:
/* Error: DONT answered by WILL */
- tn->us[option] = CURL_YES;
- tn->usq[option] = CURL_EMPTY;
+ tn->him[option] = CURL_YES;
+ tn->himq[option] = CURL_EMPTY;
break;
}
break;
case CURL_WANTYES:
- switch(tn->usq[option]) {
+ switch(tn->himq[option]) {
case CURL_EMPTY:
- tn->us[option] = CURL_YES;
- if(tn->subnegotiation[option] == CURL_YES) {
- /* transmission of data option */
- sendsuboption(data, tn, option);
- }
+ tn->him[option] = CURL_YES;
break;
case CURL_OPPOSITE:
- tn->us[option] = CURL_WANTNO;
+ tn->him[option] = CURL_WANTNO;
tn->himq[option] = CURL_EMPTY;
- send_negotiation(data, CURL_WONT, option);
+ send_negotiation(data, CURL_DONT, option);
break;
}
break;
}
}
-static void rec_dont(struct Curl_easy *data, struct TELNET *tn, int option)
+static void rec_wont(struct Curl_easy *data, struct TELNET *tn, int option)
{
- switch(tn->us[option]) {
+ switch(tn->him[option]) {
case CURL_NO:
/* Already disabled */
break;
case CURL_YES:
- tn->us[option] = CURL_NO;
- send_negotiation(data, CURL_WONT, option);
+ tn->him[option] = CURL_NO;
+ send_negotiation(data, CURL_DONT, option);
break;
case CURL_WANTNO:
- switch(tn->usq[option]) {
+ switch(tn->himq[option]) {
case CURL_EMPTY:
- tn->us[option] = CURL_NO;
+ tn->him[option] = CURL_NO;
break;
case CURL_OPPOSITE:
- tn->us[option] = CURL_WANTYES;
- tn->usq[option] = CURL_EMPTY;
- send_negotiation(data, CURL_WILL, option);
+ tn->him[option] = CURL_WANTYES;
+ tn->himq[option] = CURL_EMPTY;
+ send_negotiation(data, CURL_DO, option);
break;
}
break;
case CURL_WANTYES:
- switch(tn->usq[option]) {
+ switch(tn->himq[option]) {
case CURL_EMPTY:
- tn->us[option] = CURL_NO;
+ tn->him[option] = CURL_NO;
break;
case CURL_OPPOSITE:
- tn->us[option] = CURL_NO;
- tn->usq[option] = CURL_EMPTY;
+ tn->him[option] = CURL_NO;
+ tn->himq[option] = CURL_EMPTY;
break;
}
break;
break;
}
}
- else
- infof(data, "%d (unknown)", pointer[0]);
+ else
+ infof(data, "%d (unknown)", pointer[0]);
+
+ switch(pointer[0]) {
+ case CURL_TELOPT_NAWS:
+ if(length > 4)
+ infof(data, "Width: %d ; Height: %d", (pointer[1] << 8) | pointer[2],
+ (pointer[3] << 8) | pointer[4]);
+ break;
+ default:
+ switch(pointer[1]) {
+ case CURL_TELQUAL_IS:
+ infof(data, " IS");
+ break;
+ case CURL_TELQUAL_SEND:
+ infof(data, " SEND");
+ break;
+ case CURL_TELQUAL_INFO:
+ infof(data, " INFO/REPLY");
+ break;
+ case CURL_TELQUAL_NAME:
+ infof(data, " NAME");
+ break;
+ }
+
+ switch(pointer[0]) {
+ case CURL_TELOPT_TTYPE:
+ case CURL_TELOPT_XDISPLOC:
+ infof(data, " \"%.*s\"",
+ (int)((length > 2) ? (length - 2) : 0), &pointer[2]);
+ break;
+ case CURL_TELOPT_NEW_ENVIRON:
+ if(pointer[1] == CURL_TELQUAL_IS) {
+ infof(data, " ");
+ for(i = 3; i < length; i++) {
+ switch(pointer[i]) {
+ case CURL_NEW_ENV_VAR:
+ infof(data, ", ");
+ break;
+ case CURL_NEW_ENV_VALUE:
+ infof(data, " = ");
+ break;
+ default:
+ infof(data, "%c", pointer[i]);
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ for(i = 2; i < length; i++)
+ infof(data, " %.2x", pointer[i]);
+ break;
+ }
+ }
+ }
+}
+
+/* Escape and send a telnet data block */
+static CURLcode send_telnet_data(struct Curl_easy *data,
+ struct TELNET *tn,
+ char *buffer, ssize_t nread)
+{
+ size_t i, outlen;
+ unsigned char *outbuf;
+ CURLcode result = CURLE_OK;
+ size_t bytes_written;
+ size_t total_written = 0;
+ struct connectdata *conn = data->conn;
+
+ DEBUGASSERT(tn);
+ DEBUGASSERT(nread > 0);
+ if(nread < 0)
+ return CURLE_TOO_LARGE;
+
+ if(memchr(buffer, CURL_IAC, nread)) {
+ /* only use the escape buffer when necessary */
+ curlx_dyn_reset(&tn->out);
+
+ for(i = 0; i < (size_t)nread && !result; i++) {
+ result = curlx_dyn_addn(&tn->out, &buffer[i], 1);
+ if(!result && ((unsigned char)buffer[i] == CURL_IAC))
+ /* IAC is FF in hex */
+ result = curlx_dyn_addn(&tn->out, "\xff", 1);
+ }
+
+ outlen = curlx_dyn_len(&tn->out);
+ outbuf = curlx_dyn_uptr(&tn->out);
+ }
+ else {
+ outlen = (size_t)nread;
+ outbuf = (unsigned char *)buffer;
+ }
+ while(!result && total_written < outlen) {
+ /* Make sure socket is writable to avoid EWOULDBLOCK condition */
+ struct pollfd pfd[1];
+ pfd[0].fd = conn->sock[FIRSTSOCKET];
+ pfd[0].events = POLLOUT;
+ switch(Curl_poll(pfd, 1, -1)) {
+ case -1: /* error, abort writing */
+ case 0: /* timeout (will never happen) */
+ result = CURLE_SEND_ERROR;
+ break;
+ default: /* write! */
+ bytes_written = 0;
+ result = Curl_xfer_send(data, outbuf + total_written,
+ outlen - total_written, FALSE, &bytes_written);
+ total_written += bytes_written;
+ break;
+ }
+ }
+
+ return result;
+}
+
+/*
+ * sendsuboption()
+ *
+ * Send suboption information to the server side.
+ */
+static void sendsuboption(struct Curl_easy *data,
+ struct TELNET *tn, int option)
+{
+ ssize_t bytes_written;
+ int err;
+ unsigned short x, y;
+ unsigned char *uc1, *uc2;
+ struct connectdata *conn = data->conn;
+
+ switch(option) {
+ case CURL_TELOPT_NAWS:
+ /* We prepare data to be sent */
+ CURL_SB_CLEAR(tn);
+ CURL_SB_ACCUM(tn, CURL_IAC);
+ CURL_SB_ACCUM(tn, CURL_SB);
+ CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS);
+ /* We must deal either with little or big endian processors */
+ /* Window size must be sent according to the 'network order' */
+ x = htons(tn->subopt_wsx);
+ y = htons(tn->subopt_wsy);
+ uc1 = (unsigned char *)&x;
+ uc2 = (unsigned char *)&y;
+ CURL_SB_ACCUM(tn, uc1[0]);
+ CURL_SB_ACCUM(tn, uc1[1]);
+ CURL_SB_ACCUM(tn, uc2[0]);
+ CURL_SB_ACCUM(tn, uc2[1]);
+
+ CURL_SB_ACCUM(tn, CURL_IAC);
+ CURL_SB_ACCUM(tn, CURL_SE);
+ CURL_SB_TERM(tn);
+ /* data suboption is now ready */
+
+ printsub(data, '>', (unsigned char *)tn->subbuffer + 2,
+ CURL_SB_LEN(tn) - 2);
+
+ /* we send the header of the suboption... */
+ bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer, 3);
+ if(bytes_written < 0) {
+ err = SOCKERRNO;
+ failf(data, "Sending data failed (%d)", err);
+ }
+ /* ... then the window size with the send_telnet_data() function
+ to deal with 0xFF cases ... */
+ send_telnet_data(data, tn, (char *)tn->subbuffer + 3, 4);
+ /* ... and the footer */
+ bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer + 7, 2);
+ if(bytes_written < 0) {
+ err = SOCKERRNO;
+ failf(data, "Sending data failed (%d)", err);
+ }
+ break;
+ }
+}
+
+static void rec_do(struct Curl_easy *data, struct TELNET *tn, int option)
+{
+ switch(tn->us[option]) {
+ case CURL_NO:
+ if(tn->us_preferred[option] == CURL_YES) {
+ tn->us[option] = CURL_YES;
+ send_negotiation(data, CURL_WILL, option);
+ if(tn->subnegotiation[option] == CURL_YES)
+ /* transmission of data option */
+ sendsuboption(data, tn, option);
+ }
+ else if(tn->subnegotiation[option] == CURL_YES) {
+ /* send information to achieve this option */
+ tn->us[option] = CURL_YES;
+ send_negotiation(data, CURL_WILL, option);
+ sendsuboption(data, tn, option);
+ }
+ else
+ send_negotiation(data, CURL_WONT, option);
+ break;
+
+ case CURL_YES:
+ /* Already enabled */
+ break;
+
+ case CURL_WANTNO:
+ switch(tn->usq[option]) {
+ case CURL_EMPTY:
+ /* Error: DONT answered by WILL */
+ tn->us[option] = CURL_NO;
+ break;
+ case CURL_OPPOSITE:
+ /* Error: DONT answered by WILL */
+ tn->us[option] = CURL_YES;
+ tn->usq[option] = CURL_EMPTY;
+ break;
+ }
+ break;
+
+ case CURL_WANTYES:
+ switch(tn->usq[option]) {
+ case CURL_EMPTY:
+ tn->us[option] = CURL_YES;
+ if(tn->subnegotiation[option] == CURL_YES) {
+ /* transmission of data option */
+ sendsuboption(data, tn, option);
+ }
+ break;
+ case CURL_OPPOSITE:
+ tn->us[option] = CURL_WANTNO;
+ tn->himq[option] = CURL_EMPTY;
+ send_negotiation(data, CURL_WONT, option);
+ break;
+ }
+ break;
+ }
+}
- switch(pointer[0]) {
- case CURL_TELOPT_NAWS:
- if(length > 4)
- infof(data, "Width: %d ; Height: %d", (pointer[1] << 8) | pointer[2],
- (pointer[3] << 8) | pointer[4]);
+static void rec_dont(struct Curl_easy *data, struct TELNET *tn, int option)
+{
+ switch(tn->us[option]) {
+ case CURL_NO:
+ /* Already disabled */
+ break;
+
+ case CURL_YES:
+ tn->us[option] = CURL_NO;
+ send_negotiation(data, CURL_WONT, option);
+ break;
+
+ case CURL_WANTNO:
+ switch(tn->usq[option]) {
+ case CURL_EMPTY:
+ tn->us[option] = CURL_NO;
break;
- default:
- switch(pointer[1]) {
- case CURL_TELQUAL_IS:
- infof(data, " IS");
- break;
- case CURL_TELQUAL_SEND:
- infof(data, " SEND");
- break;
- case CURL_TELQUAL_INFO:
- infof(data, " INFO/REPLY");
- break;
- case CURL_TELQUAL_NAME:
- infof(data, " NAME");
- break;
- }
- switch(pointer[0]) {
- case CURL_TELOPT_TTYPE:
- case CURL_TELOPT_XDISPLOC:
- infof(data, " \"%.*s\"",
- (int)((length > 2) ? (length - 2) : 0), &pointer[2]);
- break;
- case CURL_TELOPT_NEW_ENVIRON:
- if(pointer[1] == CURL_TELQUAL_IS) {
- infof(data, " ");
- for(i = 3; i < length; i++) {
- switch(pointer[i]) {
- case CURL_NEW_ENV_VAR:
- infof(data, ", ");
- break;
- case CURL_NEW_ENV_VALUE:
- infof(data, " = ");
- break;
- default:
- infof(data, "%c", pointer[i]);
- break;
- }
- }
- }
- break;
- default:
- for(i = 2; i < length; i++)
- infof(data, " %.2x", pointer[i]);
- break;
- }
+ case CURL_OPPOSITE:
+ tn->us[option] = CURL_WANTYES;
+ tn->usq[option] = CURL_EMPTY;
+ send_negotiation(data, CURL_WILL, option);
+ break;
+ }
+ break;
+
+ case CURL_WANTYES:
+ switch(tn->usq[option]) {
+ case CURL_EMPTY:
+ tn->us[option] = CURL_NO;
+ break;
+ case CURL_OPPOSITE:
+ tn->us[option] = CURL_NO;
+ tn->usq[option] = CURL_EMPTY;
+ break;
}
+ break;
}
}
return CURLE_OK;
}
-/*
- * sendsuboption()
- *
- * Send suboption information to the server side.
- */
-static void sendsuboption(struct Curl_easy *data,
- struct TELNET *tn, int option)
-{
- ssize_t bytes_written;
- int err;
- unsigned short x, y;
- unsigned char *uc1, *uc2;
- struct connectdata *conn = data->conn;
-
- switch(option) {
- case CURL_TELOPT_NAWS:
- /* We prepare data to be sent */
- CURL_SB_CLEAR(tn);
- CURL_SB_ACCUM(tn, CURL_IAC);
- CURL_SB_ACCUM(tn, CURL_SB);
- CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS);
- /* We must deal either with little or big endian processors */
- /* Window size must be sent according to the 'network order' */
- x = htons(tn->subopt_wsx);
- y = htons(tn->subopt_wsy);
- uc1 = (unsigned char *)&x;
- uc2 = (unsigned char *)&y;
- CURL_SB_ACCUM(tn, uc1[0]);
- CURL_SB_ACCUM(tn, uc1[1]);
- CURL_SB_ACCUM(tn, uc2[0]);
- CURL_SB_ACCUM(tn, uc2[1]);
-
- CURL_SB_ACCUM(tn, CURL_IAC);
- CURL_SB_ACCUM(tn, CURL_SE);
- CURL_SB_TERM(tn);
- /* data suboption is now ready */
-
- printsub(data, '>', (unsigned char *)tn->subbuffer + 2,
- CURL_SB_LEN(tn) - 2);
-
- /* we send the header of the suboption... */
- bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer, 3);
- if(bytes_written < 0) {
- err = SOCKERRNO;
- failf(data, "Sending data failed (%d)", err);
- }
- /* ... then the window size with the send_telnet_data() function
- to deal with 0xFF cases ... */
- send_telnet_data(data, tn, (char *)tn->subbuffer + 3, 4);
- /* ... and the footer */
- bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer + 7, 2);
- if(bytes_written < 0) {
- err = SOCKERRNO;
- failf(data, "Sending data failed (%d)", err);
- }
- break;
- }
-}
-
static CURLcode telrcv(struct Curl_easy *data,
struct TELNET *tn,
const unsigned char *inbuf, /* Data received from
return CURLE_OK;
}
-/* Escape and send a telnet data block */
-static CURLcode send_telnet_data(struct Curl_easy *data,
- struct TELNET *tn,
- char *buffer, ssize_t nread)
-{
- size_t i, outlen;
- unsigned char *outbuf;
- CURLcode result = CURLE_OK;
- size_t bytes_written;
- size_t total_written = 0;
- struct connectdata *conn = data->conn;
-
- DEBUGASSERT(tn);
- DEBUGASSERT(nread > 0);
- if(nread < 0)
- return CURLE_TOO_LARGE;
-
- if(memchr(buffer, CURL_IAC, nread)) {
- /* only use the escape buffer when necessary */
- curlx_dyn_reset(&tn->out);
-
- for(i = 0; i < (size_t)nread && !result; i++) {
- result = curlx_dyn_addn(&tn->out, &buffer[i], 1);
- if(!result && ((unsigned char)buffer[i] == CURL_IAC))
- /* IAC is FF in hex */
- result = curlx_dyn_addn(&tn->out, "\xff", 1);
- }
-
- outlen = curlx_dyn_len(&tn->out);
- outbuf = curlx_dyn_uptr(&tn->out);
- }
- else {
- outlen = (size_t)nread;
- outbuf = (unsigned char *)buffer;
- }
- while(!result && total_written < outlen) {
- /* Make sure socket is writable to avoid EWOULDBLOCK condition */
- struct pollfd pfd[1];
- pfd[0].fd = conn->sock[FIRSTSOCKET];
- pfd[0].events = POLLOUT;
- switch(Curl_poll(pfd, 1, -1)) {
- case -1: /* error, abort writing */
- case 0: /* timeout (will never happen) */
- result = CURLE_SEND_ERROR;
- break;
- default: /* write! */
- bytes_written = 0;
- result = Curl_xfer_send(data, outbuf + total_written,
- outlen - total_written, FALSE, &bytes_written);
- total_written += bytes_written;
- break;
- }
- }
-
- return result;
-}
-
static CURLcode telnet_done(struct Curl_easy *data,
CURLcode status, bool premature)
{
return result;
}
-#endif
+
+/*
+ * TELNET protocol handler.
+ */
+const struct Curl_handler Curl_handler_telnet = {
+ "telnet", /* scheme */
+ ZERO_NULL, /* setup_connection */
+ telnet_do, /* do_it */
+ telnet_done, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_pollset */
+ ZERO_NULL, /* doing_pollset */
+ ZERO_NULL, /* domore_pollset */
+ ZERO_NULL, /* perform_pollset */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* write_resp */
+ ZERO_NULL, /* write_resp_hd */
+ ZERO_NULL, /* connection_check */
+ ZERO_NULL, /* attach connection */
+ ZERO_NULL, /* follow */
+ PORT_TELNET, /* defport */
+ CURLPROTO_TELNET, /* protocol */
+ CURLPROTO_TELNET, /* family */
+ PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
+};
+
+#endif /* !CURL_DISABLE_TELNET */