}
+void XPrint(const char *Token, long tlen,
+ int Flags,
+ ...)
+
+{
+ int BodySeen = 0;
+ int ArgType;
+ int Finished = 0;
+ char *PName;
+ long PLen;
+ char *Val;
+ long VLen;
+ va_list arg_ptr;
+
+ XPUT("<");
+ XPut(Token, tlen);
+
+ va_start(arg_ptr, Flags);
+ while (!Finished)
+ {
+ ArgType = va_arg(arg_ptr, int);
+ switch (ArgType)
+ {
+ case TYPE_STR:
+ PName = va_arg(arg_ptr, char*);
+ PLen = va_arg(arg_ptr, long);
+ Val = va_arg(arg_ptr, char*);
+ VLen = va_arg(arg_ptr, long);
+ XPUT(" ");
+ XPut(PName, PLen);
+ XPUT("=\"");
+ XPutProp(Val, VLen);
+ XPUT("\"");
+ break;
+ case TYPE_OPTSTR:
+ PName = va_arg(arg_ptr, char*);
+ PLen = va_arg(arg_ptr, long);
+ Val = va_arg(arg_ptr, char*);
+ VLen = va_arg(arg_ptr, long);
+ if (VLen > 0)
+ {
+ XPUT(" ");
+ XPut(PName, PLen);
+ XPUT("=\"");
+ XPutProp(Val, VLen);
+ XPUT("\"");
+ }
+ break;
+ case TYPE_INT:
+ PName = va_arg(arg_ptr, char*);
+ PLen = va_arg(arg_ptr, long);
+ VLen = va_arg(arg_ptr, long);
+ XPUT(" ");
+ XPut(PName, PLen);
+ XPUT("=\"");
+ XPrintf("%ld", VLen);
+ XPUT("\"");
+ break;
+ case TYPE_BODYSTR:
+ BodySeen = 1;
+ XPUT(">");
+ Val = va_arg(arg_ptr, char*);
+ VLen = va_arg(arg_ptr, long);
+ XPutBody(Val, VLen);
+ break;
+ case TYPE_ARGEND:
+ Finished = 1;
+ break;
+ }
+ }
+ if (Flags == XCLOSED)
+ {
+ if (BodySeen)
+ {
+ XPUT("</");
+ XPut(Token, tlen);
+ XPUT(">");
+ }
+ else
+ {
+ XPUT("></");
+ XPut(Token, tlen);
+ XPUT(">");
+ }
+ }
+ else
+ XPUT(">");
+ va_end(arg_ptr);
+}
+
#ifdef HAVE_XML_STOPPARSER
/* Stop the parser if an entity declaration is hit. */
static void xmpp_entity_declaration(void *userData, const XML_Char *entityName,
long len,
xmpp_handler_func Handler,
int Flags);
+
+
+#define XCLOSED (1<<0)
+void XPrint(const char *Token, long tlen,
+ int Flags,
+ ...);
+
+#define TYPE_STR 1
+#define TYPE_OPTSTR 2
+#define TYPE_INT 3
+#define TYPE_BODYSTR 4
+#define TYPE_ARGEND 5
+#define XPROPERTY(NAME, VALUE, VLEN) TYPE_STR, NAME, sizeof(NAME)-1, VALUE, VLEN
+#define XOPROPERTY(NAME, VALUE, VLEN) TYPE_OPTSTR, NAME, sizeof(NAME)-1, VALUE, VLEN
+#define XCPROPERTY(NAME, VALUE) TYPE_STR, NAME, sizeof(NAME)-1, VALUE, sizeof(VALUE) - 1
+#define XIPROPERTY(NAME, LVALUE) TYPE_INT, NAME, SIZEOF(NAME)-1
+#define XBODY(VALUE, VLEN) TYPE_BODYSTR, VALUE, VLEN
+#define XCFGBODY(WHICH) TYPE_BODYSTR, config.WHICH, configlen.WHICH
CCC->FirstExpressMessage = CCC->FirstExpressMessage->next;
end_critical_section(S_SESSION_TABLE);
-
- XPUT("<message type=\"chat\" to=\"");
- XPutProp(Xmpp->client_jid, strlen(Xmpp->client_jid));
- XPUT("\" from=\"");
- XPutProp(ptr->sender_email, strlen(ptr->sender_email));
- XPUT("\" >");
+ XPrint(HKEY("message"), 0,
+ XCPROPERTY("type", "chat"),
+ XPROPERTY("to", Xmpp->client_jid, strlen(Xmpp->client_jid)),
+ XPROPERTY("from", ptr->sender_email, strlen(ptr->sender_email)),
+ TYPE_ARGEND);
if (ptr->text != NULL) {
striplt(ptr->text);
- XPUT("<body>");
- XPutBody(ptr->text, strlen(ptr->text));
- XPUT("</body>");
+ XPrint(HKEY("body"), XCLOSED,
+ XBODY(ptr->text, strlen(ptr->text)),
+ TYPE_ARGEND);
free(ptr->text);
}
XPUT("</message>");
*/
void xmpp_indicate_presence(char *presence_jid)
{
- XPUT("<presence from=\"");
- XPutProp(presence_jid, strlen(presence_jid));
- XPUT("\" to=\"");
- XPutProp(XMPP->client_jid, strlen(XMPP->client_jid));
- XPUT("\"></presence>");
+ XPrint(HKEY("presence"),
+ XPROPERTY("from", presence_jid, strlen(presence_jid)),
+ XPROPERTY("to", XMPP->client_jid, strlen(XMPP->client_jid)),
+ TYPE_ARGEND);
}
void xmpp_destroy_buddy(char *presence_jid, int aggressively) {
static int unsolicited_id = 1;
struct CitContext *CCC = CC;
+ char Buf[64];
+ long blen;
if (!presence_jid) return;
if (!XMPP) return;
if (!XMPP->client_jid) return;
/* Transmit non-presence information */
- XPUT("<presence type=\"unavailable\" from=\"");
- XPutProp(presence_jid, strlen(presence_jid));
- XPUT("\" to=\"");
- XPutProp(XMPP->client_jid, strlen(XMPP->client_jid));
- XPUT("\"></presence>");
+ XPrint(HKEY("presence"), XCLOSED,
+ XCPROPERTY("type", "unavailable"),
+ XPROPERTY("from", presence_jid, strlen(presence_jid)),
+ XPROPERTY("to", XMPP->client_jid, strlen(XMPP->client_jid)),
+ TYPE_ARGEND);
/*
* Setting the "aggressively" flag also sends an "unsubscribed" presence update.
* it as a rejection of a subscription request.
*/
if (aggressively) {
- XPUT("<presence type=\"unsubscribed\" from=\"");
- XPutProp(presence_jid, strlen(presence_jid));
- XPUT("\" to=\"");
- XPutProp(XMPP->client_jid, strlen(XMPP->client_jid));
- XPUT("\"></presence>");
+ XPrint(HKEY("presence"), XCLOSED,
+ XCPROPERTY("type", "unsubscribed"),
+ XPROPERTY("from", presence_jid, strlen(presence_jid)),
+ XPROPERTY("to", XMPP->client_jid, strlen(XMPP->client_jid)),
+ TYPE_ARGEND);
}
// FIXME ... we should implement xmpp_indicate_nonpresence so we can use it elsewhere
+ blen = snprintf(Buf, sizeof(Buf), "unbuddy_%x", ++unsolicited_id);
+
/* Do an unsolicited roster update that deletes the contact. */
- XPUT("<iq type=\"result\" from=\"");
- XPutProp(CCC->cs_inet_email, strlen(CCC->cs_inet_email));
- XPUT("\" to=\"");
- XPutProp(XMPP->client_jid, strlen(XMPP->client_jid));
- XPUT("\" id=\"unbuddy_");
- XPrintf("%x", ++unsolicited_id);
- XPUT("\">");
-
- XPUT("<query xmlns=\"jabber:iq:roster\">"
- "<item subscription=\"remove\" jid=\"");
- XPutProp(presence_jid, strlen(presence_jid));
- XPUT("\">"
- "<group>");
- XPutBody(CFG_KEY(c_humannode));
- XPUT("</group>"
- "</item>"
+ XPrint(HKEY("iq"), 0,
+ XCPROPERTY("type", "result"),
+ XPROPERTY("from", CCC->cs_inet_email, strlen(CCC->cs_inet_email)),
+ XPROPERTY("to", XMPP->client_jid, strlen(XMPP->client_jid)),
+ XPROPERTY("id", Buf, blen),
+ TYPE_ARGEND);
+
+ XPrint(HKEY("query"), 0,
+ XCPROPERTY("xmlns", "jabber:iq:roster"),
+ TYPE_ARGEND);
+
+ XPrint(HKEY("item"), 0,
+ XCPROPERTY("subscription", "remove"),
+ XPROPERTY("jid", presence_jid, strlen(presence_jid)),
+ TYPE_ARGEND);
+
+ XPrint(HKEY("group"), XCLOSED,
+ XCFGBODY(c_humannode),
+ TYPE_ARGEND);
+ XPUT("</item>"
"</query>"
"</iq>"
);
visible_sessions, presence_jid, CC->cs_pid);
if ( (event_type == XMPP_EVT_LOGIN) && (visible_sessions == 1) ) {
+ long blen;
+ char Buf[64];
XMPP_syslog(LOG_DEBUG, "Telling session %d that <%s> logged in\n",
CC->cs_pid, presence_jid);
/* Do an unsolicited roster update that adds a new contact. */
assert(which_cptr_is_relevant >= 0);
- XPUT("<iq type=\"result\" id=\"unsolicited_");
- XPrintf("%x", ++unsolicited_id);
- XPUT("\" >"
- "<query xmlns=\"jabber:iq:roster\">");
+
+ blen = snprintf(Buf, sizeof(Buf), "unsolicited_%x", ++unsolicited_id);
+
+ XPrint(HKEY("iq"), 0,
+ XCPROPERTY("type", "result"),
+ XPROPERTY("id", Buf, blen),
+ TYPE_ARGEND);
+
+ XPrint(HKEY("query"), 0,
+ XCPROPERTY("xmlns", "jabber:iq:roster"),
+ TYPE_ARGEND);
+
xmpp_roster_item(&cptr[which_cptr_is_relevant]);
XPUT("</query></iq>");
*/
void xmpp_roster_item(struct CitContext *cptr)
{
+ struct CitContext *CCC=CC;
- XPUT("<item subscription=\"both\" jid=\"");
- XPutProp(cptr->cs_inet_email, strlen(cptr->cs_inet_email));
- XPUT("\" name=\"");
- XPutProp(cptr->user.fullname, strlen(cptr->user.fullname));
- XPUT("\">"
- "<group>");
- XPutBody(CFG_KEY(c_humannode));
- XPUT("</group>"
- "</item>");
+ XPrint(HKEY("item"), 0,
+ XCPROPERTY("subscription", "both"),
+ XPROPERTY("jid", CCC->cs_inet_email, strlen(CCC->cs_inet_email)),
+ XPROPERTY("name", cptr->user.fullname, strlen(cptr->user.fullname)),
+ TYPE_ARGEND);
+
+ XPrint(HKEY("group"), XCLOSED,
+ XCFGBODY(c_humannode),
+ TYPE_ARGEND);
+
+ XPUT("</item>");
}
/*
{
int supported_namespace = 0;
int roster_query = 0;
-
+ const char *TypeStr;
+ long TLen;
+ ConstStr Type[] = {
+ {HKEY("result")},
+ {HKEY("error")}
+ };
+
/* We need to know before we begin the response whether this is a supported namespace, so
* unfortunately all supported namespaces need to be defined here *and* down below where
* they are handled.
* Beginning of query result.
*/
if (supported_namespace) {
- XPUT("<iq type=\"result\" ");
+ TypeStr = Type[0].Key;
+ TLen = Type[0].len;
}
else {
- XPUT("<iq type=\"error\" ");
+ TypeStr = Type[1].Key;
+ TLen = Type[1].len;
}
- if (!IsEmptyStr(iq_from)) {
- XPUT("to=\"");
- XPutProp(iq_from, strlen(iq_from));
- XPUT("\" ");
- }
- XPUT("id=\"");
- XPutProp(iq_id, strlen(iq_id));
- XPUT("\">");
+
+ XPrint(HKEY("iq"), 0,
+ XPROPERTY("type", TypeStr, TLen),
+ XOPROPERTY("to", iq_from, strlen(iq_from)),
+ XPROPERTY("id", iq_id, strlen(iq_id)));
/*
* Is this a query we know how to handle?
if (result == login_ok) {
result = CtdlTryPassword(password, strlen(password));
if (result == pass_ok) {
- XPUT("<iq type=\"result\" id=\"");
- XPutProp(iq_id, strlen(iq_id));
- XPUT("\"></iq>"); /* success */
+ XPrint(HKEY("iq"), XCLOSED,
+ XCPROPERTY("type", "result"),
+ XPROPERTY("ID", iq_id, strlen(iq_id)),
+ TYPE_ARGEND);
+ /* success */
return;
}
}
/* failure */
- XPUT("<iq type=\"error\" id=\"");
- XPutProp(iq_id, strlen(iq_id));
- XPUT("\">"
- "<error code=\"401\" type=\"auth\">"
+ XPrint(HKEY("iq"), 0,
+ XCPROPERTY("type", "error"),
+ XPROPERTY("ID", iq_id, strlen(iq_id)),
+ TYPE_ARGEND);
+ XPUT("<error code=\"401\" type=\"auth\">"
"<not-authorized xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>"
"</error>"
"</iq>"