jabberd2
2.2.16
|
00001 /* 00002 * jabberd - Jabber Open Source Server 00003 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, 00004 * Ryan Eatmon, Robert Norris 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA 00019 */ 00020 00021 #include "sx.h" 00022 00024 static const char *_stream_errors[] = { 00025 "bad-format", 00026 "bad-namespace-prefix", 00027 "conflict", 00028 "connection-timeout", 00029 "host-gone", 00030 "host-unknown", 00031 "improper-addressing", 00032 "internal-server-error", 00033 "invalid-from", 00034 "invalid-id", 00035 "invalid-namespace", 00036 "invalid-xml", 00037 "not-authorized", 00038 "policy-violation", 00039 "remote-connection-failed", 00040 "restricted-xml", 00041 "resource-constraint", 00042 "see-other-host", 00043 "system-shutdown", 00044 "undefined-condition", 00045 "unsupported-encoding", 00046 "unsupported-stanza-type", 00047 "unsupported-version", 00048 "xml-not-well-formed", 00049 NULL 00050 }; 00051 00053 void _sx_error(sx_t s, int err, const char *text) { 00054 int len = 0; 00055 sx_buf_t buf; 00056 00057 /* build the string */ 00058 if(s->state < state_STREAM) len = strlen(uri_STREAMS) + 61; 00059 len += strlen(uri_STREAMS) + strlen(uri_STREAM_ERR) + strlen(_stream_errors[err]) + 58; 00060 if(text != NULL) len += strlen(uri_STREAM_ERR) + strlen(text) + 22; 00061 00062 buf = _sx_buffer_new(NULL, len, NULL, NULL); 00063 len = 0; 00064 00065 if(s->state < state_STREAM) 00066 len = sprintf(buf->data, "<stream:stream xmlns:stream='" uri_STREAMS "' version='1.0'>"); 00067 00068 if(text == NULL) 00069 len += sprintf(&(buf->data[len]), "<stream:error xmlns:stream='" uri_STREAMS "'><%s xmlns='" uri_STREAM_ERR "'/></stream:error>", _stream_errors[err]); 00070 else 00071 len += sprintf(&(buf->data[len]), "<stream:error xmlns:stream='" uri_STREAMS "'><%s xmlns='" uri_STREAM_ERR "'/><text xmlns='" uri_STREAM_ERR "'>%s</text></stream:error>", _stream_errors[err], text); 00072 00073 if(s->state < state_STREAM) 00074 len += sprintf(&(buf->data[len]), "</stream:stream>"); 00075 00076 buf->len--; 00077 assert(len == buf->len); 00078 00079 _sx_debug(ZONE, "prepared error: %.*s", buf->len, buf->data); 00080 00081 /* go */ 00082 jqueue_push(s->wbufq, buf, 0); 00083 00084 /* stuff to write */ 00085 s->want_write = 1; 00086 } 00087 00088 void sx_error(sx_t s, int err, const char *text) { 00089 assert(s != NULL); 00090 assert(err >= 0 && err < stream_err_LAST); 00091 00092 _sx_error(s, err, text); 00093 00094 _sx_event(s, event_WANT_WRITE, NULL); 00095 } 00096 00097 //** send an extended error with custom contents other than text */ 00098 // Ideally should be merged with sx_error. sx_error should permit additional content beneath the <stream:error> element, other than a <text> node. 00099 void _sx_error_extended(sx_t s, int err, const char *content) { 00100 int len = 0; 00101 sx_buf_t buf; 00102 00103 /* build the string */ 00104 if(s->state < state_STREAM) len = strlen(uri_STREAMS) + 61; 00105 len += strlen(uri_STREAMS) + strlen(uri_STREAM_ERR) + strlen(_stream_errors[err]) + 58; 00106 if(content != NULL) len += strlen(content) + strlen(_stream_errors[err]) + 2; 00107 00108 buf = _sx_buffer_new(NULL, len, NULL, NULL); 00109 len = 0; 00110 00111 if(s->state < state_STREAM) 00112 len = sprintf(buf->data, "<stream:stream xmlns:stream='" uri_STREAMS "' version='1.0'>"); 00113 00114 if(content == NULL) 00115 len += sprintf(&(buf->data[len]), "<stream:error xmlns:stream='" uri_STREAMS "'><%s xmlns='" uri_STREAM_ERR "'/></stream:error>", _stream_errors[err]); 00116 else 00117 len += sprintf(&(buf->data[len]), "<stream:error xmlns:stream='" uri_STREAMS "'><%s xmlns='" uri_STREAM_ERR "'>%s</%s></stream:error>", _stream_errors[err], content, _stream_errors[err]); 00118 00119 if(s->state < state_STREAM) 00120 len += sprintf(&(buf->data[len]), "</stream:stream>"); 00121 00122 buf->len--; 00123 assert(len == buf->len); 00124 00125 _sx_debug(ZONE, "prepared error: %.*s", buf->len, buf->data); 00126 00127 /* go */ 00128 jqueue_push(s->wbufq, buf, 0); 00129 00130 /* stuff to write */ 00131 s->want_write = 1; 00132 } 00133 00134 void sx_error_extended(sx_t s, int err, const char *content) { 00135 assert(s != NULL); 00136 assert(err >= 0 && err < stream_err_LAST); 00137 00138 _sx_error_extended(s, err, content); 00139 00140 _sx_event(s, event_WANT_WRITE, NULL); 00141 }