📄 stream.c
字号:
cdataHook (struct stream_data *data, char *cdata, size_t len){ if (data->current) iks_insert_cdata (data->current, cdata, len); return IKS_OK;}static voiddeleteHook (struct stream_data *data){#ifdef HAVE_GNUTLS if (data->flags & SF_SECURE) { gnutls_bye (data->sess, GNUTLS_SHUT_WR); gnutls_deinit (data->sess); gnutls_certificate_free_credentials (data->cred); }#endif if (data->trans) data->trans->close (data->sock); data->trans = NULL; if (data->current) iks_delete (data->current); data->current = NULL; data->flags = 0;}iksparser *iks_stream_new (char *name_space, void *user_data, iksStreamHook *streamHook){ ikstack *s; struct stream_data *data; s = iks_stack_new (DEFAULT_STREAM_CHUNK_SIZE, 0); if (NULL == s) return NULL; data = iks_stack_alloc (s, sizeof (struct stream_data)); memset (data, 0, sizeof (struct stream_data)); data->s = s; data->prs = iks_sax_extend (s, data, (iksTagHook *)tagHook, (iksCDataHook *)cdataHook, (iksDeleteHook *)deleteHook); data->name_space = name_space; data->user_data = user_data; data->streamHook = streamHook; return data->prs;}void *iks_stream_user_data (iksparser *prs){ struct stream_data *data = iks_user_data (prs); return data->user_data;}voidiks_set_log_hook (iksparser *prs, iksLogHook *logHook){ struct stream_data *data = iks_user_data (prs); data->logHook = logHook;}intiks_connect_tcp (iksparser *prs, const char *server, int port){#ifdef USE_DEFAULT_IO return iks_connect_with (prs, server, port, server, &iks_default_transport);#else return IKS_NET_NOTSUPP;#endif}intiks_connect_via (iksparser *prs, const char *server, int port, const char *server_name){#ifdef USE_DEFAULT_IO return iks_connect_with (prs, server, port, server_name, &iks_default_transport);#else return IKS_NET_NOTSUPP;#endif}intiks_connect_with (iksparser *prs, const char *server, int port, const char *server_name, ikstransport *trans){ struct stream_data *data = iks_user_data (prs); int ret; if (!trans->connect) return IKS_NET_NOTSUPP; if (!data->buf) { data->buf = iks_stack_alloc (data->s, NET_IO_BUF_SIZE); if (NULL == data->buf) return IKS_NOMEM; } ret = trans->connect (prs, &data->sock, server, port); if (ret) return ret; data->trans = trans; return iks_send_header (prs, server_name);}intiks_connect_async (iksparser *prs, const char *server, int port, void *notify_data, iksAsyncNotify *notify_func){#ifdef USE_DEFAULT_IO return iks_connect_async_with (prs, server, port, server, &iks_default_transport, notify_data, notify_func);#else return IKS_NET_NOTSUPP;#endif}intiks_connect_async_with (iksparser *prs, const char *server, int port, const char *server_name, ikstransport *trans, void *notify_data, iksAsyncNotify *notify_func){ struct stream_data *data = iks_user_data (prs); int ret; if (NULL == trans->connect_async) return IKS_NET_NOTSUPP; if (!data->buf) { data->buf = iks_stack_alloc (data->s, NET_IO_BUF_SIZE); if (NULL == data->buf) return IKS_NOMEM; } ret = trans->connect_async (prs, &data->sock, server, server_name, port, notify_data, notify_func); if (ret) return ret; data->trans = trans; data->server = server_name; return IKS_OK;}intiks_connect_fd (iksparser *prs, int fd){#ifdef USE_DEFAULT_IO struct stream_data *data = iks_user_data (prs); if (!data->buf) { data->buf = iks_stack_alloc (data->s, NET_IO_BUF_SIZE); if (NULL == data->buf) return IKS_NOMEM; } data->sock = (void *) fd; data->flags |= SF_FOREIGN; data->trans = &iks_default_transport; return IKS_OK;#else return IKS_NET_NOTSUPP;#endif}intiks_fd (iksparser *prs){ struct stream_data *data = iks_user_data (prs); return (int) data->sock;}intiks_recv (iksparser *prs, int timeout){ struct stream_data *data = iks_user_data (prs); int len, ret; while (1) {#ifdef HAVE_GNUTLS if (data->flags & SF_SECURE) { len = gnutls_record_recv (data->sess, data->buf, NET_IO_BUF_SIZE - 1); } else#endif { len = data->trans->recv (data->sock, data->buf, NET_IO_BUF_SIZE - 1, timeout); } if (len < 0) return IKS_NET_RWERR; if (len == 0) break; data->buf[len] = '\0'; if (data->logHook) data->logHook (data->user_data, data->buf, len, 1); ret = iks_parse (prs, data->buf, len, 0); if (ret != IKS_OK) return ret; if (!data->trans) { /* stream hook called iks_disconnect */ return IKS_NET_NOCONN; } timeout = 0; } return IKS_OK;}intiks_send_header (iksparser *prs, const char *to){ struct stream_data *data = iks_user_data (prs); char *msg; int len, err; len = 91 + strlen (data->name_space) + 6 + strlen (to) + 16 + 1; msg = iks_malloc (len); if (!msg) return IKS_NOMEM; sprintf (msg, "<?xml version='1.0'?>" "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='" "%s' to='%s' version='1.0'>", data->name_space, to); err = iks_send_raw (prs, msg); iks_free (msg); if (err) return err; data->server = to; return IKS_OK;}intiks_send (iksparser *prs, iks *x){ return iks_send_raw (prs, iks_string (iks_stack (x), x));}intiks_send_raw (iksparser *prs, const char *xmlstr){ struct stream_data *data = iks_user_data (prs); int ret;#ifdef HAVE_GNUTLS if (data->flags & SF_SECURE) { if (gnutls_record_send (data->sess, xmlstr, strlen (xmlstr)) < 0) return IKS_NET_RWERR; } else#endif { ret = data->trans->send (data->sock, xmlstr, strlen (xmlstr)); if (ret) return ret; } if (data->logHook) data->logHook (data->user_data, xmlstr, strlen (xmlstr), 0); return IKS_OK;}voidiks_disconnect (iksparser *prs){ iks_parser_reset (prs);}/***** tls api *****/intiks_has_tls (void){#ifdef HAVE_GNUTLS return 1;#else return 0;#endif}intiks_is_secure (iksparser *prs){#ifdef HAVE_GNUTLS struct stream_data *data = iks_user_data (prs); return data->flags & SF_SECURE;#else return 0;#endif}intiks_start_tls (iksparser *prs){#ifdef HAVE_GNUTLS int ret; struct stream_data *data = iks_user_data (prs); ret = iks_send_raw (prs, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"); if (ret) return ret; data->flags |= SF_TRY_SECURE; return IKS_OK;#else return IKS_NET_NOTSUPP;#endif}/***** sasl *****/intiks_start_sasl (iksparser *prs, enum ikssasltype type, char *username, char *pass){ iks *x; x = iks_new ("auth"); iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL); switch (type) { case IKS_SASL_PLAIN: { int len = iks_strlen (username) + iks_strlen (pass) + 2; char *s = iks_malloc (80+len); char *base64; iks_insert_attrib (x, "mechanism", "PLAIN"); sprintf (s, "%c%s%c%s", 0, username, 0, pass); base64 = iks_base64_encode (s, len); iks_insert_cdata (x, base64, 0); iks_free (base64); iks_free (s); break; } case IKS_SASL_DIGEST_MD5: { struct stream_data *data = iks_user_data (prs); iks_insert_attrib (x, "mechanism", "DIGEST-MD5"); data->auth_username = username; data->auth_pass = pass; break; } default: iks_delete (x); return IKS_NET_NOTSUPP; } iks_send (prs, x); iks_delete (x); return IKS_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -