+#ifdef HAVE_XML_STOPPARSER
+/* Stop the parser if an entity declaration is hit. */
+static void xmpp_entity_declaration(void *userData, const XML_Char *entityName,
+ int is_parameter_entity, const XML_Char *value,
+ int value_length, const XML_Char *base,
+ const XML_Char *systemId, const XML_Char *publicId,
+ const XML_Char *notationName
+) {
+ syslog(LOG_WARNING, "xmpp: illegal entity declaration encountered; stopping parser.");
+ XML_StopParser(XMPP->xp, XML_FALSE);
+}
+#endif
+
+
+/*
+ * support function for xmlesc() which helps with UTF-8 strings
+ */
+static inline int Ctdl_GetUtf8SequenceLength(const char *CharS, const char *CharE)
+{
+ int n = 0;
+ unsigned char test = (1<<7);
+
+ if ((*CharS & 0xC0) != 0xC0) {
+ return 1;
+ }
+
+ while ((n < 8) && ((test & ((unsigned char)*CharS)) != 0)) {
+ test = test >> 1;
+ n ++;
+ }
+ if ((n > 6) || ((CharE - CharS) < n)) {
+ n = 0;
+ }
+ return n;
+}
+
+
+/*
+ * Given a source string and a target buffer, returns the string
+ * properly escaped for insertion into an XML stream. Returns a
+ * pointer to the target buffer for convenience.
+ */
+char *xmlesc(char *buf, char *str, int bufsiz)
+{
+ int IsUtf8Sequence;
+ char *ptr, *pche;
+ unsigned char ch;
+ int inlen;
+ int len = 0;
+
+ if (!buf) return(NULL);
+ buf[0] = 0;
+ len = 0;
+ if (!str) {
+ return(buf);
+ }
+ inlen = strlen(str);
+ pche = str + inlen;
+
+ for (ptr=str; *ptr; ptr++) {
+ ch = *ptr;
+ if (ch == '<') {
+ strcpy(&buf[len], "<");
+ len += 4;
+ }
+ else if (ch == '>') {
+ strcpy(&buf[len], ">");
+ len += 4;
+ }
+ else if (ch == '&') {
+ strcpy(&buf[len], "&");
+ len += 5;
+ }
+ else if ((ch >= 0x20) && (ch <= 0x7F)) {
+ buf[len++] = ch;
+ buf[len] = 0;
+ }
+ else if (ch < 0x20) {
+ buf[len++] = '_'; // we probably shouldn't be doing this
+ buf[len] = 0;
+ }
+ else {
+ IsUtf8Sequence = Ctdl_GetUtf8SequenceLength(ptr, pche);
+ if (IsUtf8Sequence)
+ {
+ while ((IsUtf8Sequence > 0) &&
+ (ptr < pche))
+ {
+ buf[len] = *ptr;
+ ptr ++;
+ --IsUtf8Sequence;
+ }
+ }
+ else
+ {
+ char oct[10];
+ sprintf(oct, "&#%o;", ch);
+ strcpy(&buf[len], oct);
+ len += strlen(oct);
+ }
+ }
+ if ((len + 6) > bufsiz) {
+ return(buf);
+ }
+ }
+ return(buf);
+}
+