jabberd2  2.2.16
sx/error.c
Go to the documentation of this file.
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 }