jabberd2  2.3.2
error.c
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 #include "sx.h"
22 
24 static const char *_stream_errors[] = {
25  "bad-format",
26  "bad-namespace-prefix",
27  "conflict",
28  "connection-timeout",
29  "host-gone",
30  "host-unknown",
31  "improper-addressing",
32  "internal-server-error",
33  "invalid-from",
34  "invalid-id",
35  "invalid-namespace",
36  "invalid-xml",
37  "not-authorized",
38  "policy-violation",
39  "remote-connection-failed",
40  "restricted-xml",
41  "resource-constraint",
42  "see-other-host",
43  "system-shutdown",
44  "undefined-condition",
45  "unsupported-encoding",
46  "unsupported-stanza-type",
47  "unsupported-version",
48  "xml-not-well-formed",
49  NULL
50 };
51 
53 void _sx_error(sx_t s, int err, const char *text) {
54  int len = 0;
55  sx_buf_t buf;
56 
57  /* build the string */
58  if(s->state < state_STREAM) len = strlen(uri_STREAMS) + 61;
59  len += strlen(uri_STREAMS) + strlen(uri_STREAM_ERR) + strlen(_stream_errors[err]) + 58;
60  if(text != NULL) len += strlen(uri_STREAM_ERR) + strlen(text) + 22;
61 
62  buf = _sx_buffer_new(NULL, len, NULL, NULL);
63  len = 0;
64 
65  if(s->state < state_STREAM)
66  len = sprintf(buf->data, "<stream:stream xmlns:stream='" uri_STREAMS "' version='1.0'>");
67 
68  if(text == NULL)
69  len += sprintf(&(buf->data[len]), "<stream:error xmlns:stream='" uri_STREAMS "'><%s xmlns='" uri_STREAM_ERR "'/></stream:error>", _stream_errors[err]);
70  else
71  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);
72 
73  if(s->state < state_STREAM)
74  len += sprintf(&(buf->data[len]), "</stream:stream>");
75 
76  buf->len--;
77  assert(len == buf->len);
78 
79  _sx_debug(ZONE, "prepared error: %.*s", buf->len, buf->data);
80 
81  /* go */
82  jqueue_push(s->wbufq, buf, 0);
83 
84  /* stuff to write */
85  s->want_write = 1;
86 }
87 
88 void sx_error(sx_t s, int err, const char *text) {
89  assert(s != NULL);
90  assert(err >= 0 && err < stream_err_LAST);
91 
92  _sx_error(s, err, text);
93 
94  _sx_event(s, event_WANT_WRITE, NULL);
95 }
96 
97 //** send an extended error with custom contents other than text */
98 // Ideally should be merged with sx_error. sx_error should permit additional content beneath the <stream:error> element, other than a <text> node.
99 void _sx_error_extended(sx_t s, int err, const char *content) {
100  int len = 0;
101  sx_buf_t buf;
102 
103  /* build the string */
104  if(s->state < state_STREAM) len = strlen(uri_STREAMS) + 61;
105  len += strlen(uri_STREAMS) + strlen(uri_STREAM_ERR) + strlen(_stream_errors[err]) + 58;
106  if(content != NULL) len += strlen(content) + strlen(_stream_errors[err]) + 2;
107 
108  buf = _sx_buffer_new(NULL, len, NULL, NULL);
109  len = 0;
110 
111  if(s->state < state_STREAM)
112  len = sprintf(buf->data, "<stream:stream xmlns:stream='" uri_STREAMS "' version='1.0'>");
113 
114  if(content == NULL)
115  len += sprintf(&(buf->data[len]), "<stream:error xmlns:stream='" uri_STREAMS "'><%s xmlns='" uri_STREAM_ERR "'/></stream:error>", _stream_errors[err]);
116  else
117  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]);
118 
119  if(s->state < state_STREAM)
120  len += sprintf(&(buf->data[len]), "</stream:stream>");
121 
122  buf->len--;
123  assert(len == buf->len);
124 
125  _sx_debug(ZONE, "prepared error: %.*s", buf->len, buf->data);
126 
127  /* go */
128  jqueue_push(s->wbufq, buf, 0);
129 
130  /* stuff to write */
131  s->want_write = 1;
132 }
133 
134 void sx_error_extended(sx_t s, int err, const char *content) {
135  assert(s != NULL);
136  assert(err >= 0 && err < stream_err_LAST);
137 
138  _sx_error_extended(s, err, content);
139 
140  _sx_event(s, event_WANT_WRITE, NULL);
141 }
Definition: sx.h:113
_sx_state_t state
Definition: sx.h:313
#define _sx_event(s, e, data)
Definition: sx.h:392
jqueue_t wbufq
Definition: sx.h:299
void _sx_error_extended(sx_t s, int err, const char *content)
Definition: error.c:99
static const char * _stream_errors[]
if you change these, reflect your changes in the defines in sx.h
Definition: error.c:24
holds the state for a single stream
Definition: sx.h:251
char * data
Definition: sx.h:114
void jqueue_push(jqueue_t q, void *data, int priority)
Definition: jqueue.c:44
#define stream_err_LAST
Definition: sx.h:148
sx_buf_t _sx_buffer_new(const char *data, int len, _sx_notify_t notify, void *notify_arg)
utility: make a new buffer if len>0 but data is NULL, the buffer will contain that many bytes of garb...
Definition: sx.c:222
void sx_error_extended(sx_t s, int err, const char *content)
Definition: error.c:134
#define _sx_debug
Definition: sx.h:405
#define uri_STREAMS
Definition: uri.h:34
void sx_error(sx_t s, int err, const char *text)
Definition: error.c:88
unsigned int len
Definition: sx.h:115
#define uri_STREAM_ERR
Definition: uri.h:49
void _sx_error(sx_t s, int err, const char *text)
send an error
Definition: error.c:53
#define ZONE
Definition: mio_impl.h:76
int want_write
Definition: sx.h:304