From 85a4d8d0b5af0edda2a0fa27c66457b775eb1209 Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Sun, 10 Nov 2013 09:57:49 +0100 Subject: [PATCH] XMPP: add X-Macros to automated parse tokens --- citadel/modules/xmpp/serv_xmpp.c | 190 +++++++++++++++++--- citadel/modules/xmpp/serv_xmpp.h | 41 ++--- citadel/modules/xmpp/token.def | 20 +++ citadel/modules/xmpp/xmpp_query_namespace.c | 8 +- citadel/modules/xmpp/xmpp_sasl_service.c | 6 +- citadel/modules/xmpp/xmpp_util.h | 49 +++++ citadel/modules/xmpp/xmpp_xmacros.c | 101 +++++++++++ citadel/modules/xmpp/xmpp_xmacros.h | 35 ++++ 8 files changed, 387 insertions(+), 63 deletions(-) create mode 100644 citadel/modules/xmpp/token.def create mode 100644 citadel/modules/xmpp/xmpp_util.h create mode 100644 citadel/modules/xmpp/xmpp_xmacros.c create mode 100644 citadel/modules/xmpp/xmpp_xmacros.h diff --git a/citadel/modules/xmpp/serv_xmpp.c b/citadel/modules/xmpp/serv_xmpp.c index daf1db7c6..b06d11aef 100644 --- a/citadel/modules/xmpp/serv_xmpp.c +++ b/citadel/modules/xmpp/serv_xmpp.c @@ -67,6 +67,9 @@ struct xmpp_event *xmpp_queue = NULL; HashList *XMPP_StartHandlers = NULL; HashList *XMPP_EndHandlers = NULL; +HashList *XMPP_SupportedNamespaces = NULL; +HashList *XMPP_NameSpaces = 0; +HashList *FlatToken = NULL; int XMPPSrvDebugEnable = 0; @@ -92,7 +95,6 @@ void XPut(const char *Str, long Len) { StrBufAppendBufPlain(XMPP->OutBuf, Str, Len, 0); } -#define XPUT(CONSTSTR) XPut(CONSTSTR, sizeof(CONSTSTR) -1) void XPrintf(const char *Format, ...) { @@ -236,12 +238,13 @@ void xmpp_stream_start(void *data, const char *supplied_el, const char **attr) /* * TLS encryption (but only if it isn't already active) */ +/* #ifdef HAVE_OPENSSL if (!CC->redirect_ssl) { XPUT(""); } #endif - +*/ if (!CC->logged_in) { /* If we're not logged in yet, offer SASL as our feature set */ xmpp_output_auth_mechs(); @@ -271,6 +274,7 @@ void xmpp_start_bind(void *data, const char *supplied_el, const char **attr) void xmpp_start_iq(void *data, const char *supplied_el, const char **attr) { +/* int i; for (i=0; attr[i] != NULL; i+=2) { if (!strcasecmp(attr[i], "type")) { @@ -286,6 +290,7 @@ void xmpp_start_iq(void *data, const char *supplied_el, const char **attr) safestrncpy(XMPP->iq_to, attr[i+1], sizeof XMPP->iq_to); } } +*/ } void xmpp_start_auth(void *data, const char *supplied_el, const char **attr) @@ -318,8 +323,11 @@ void xmpp_start_html(void *data, const char *supplied_el, const char **attr) void xmpp_xml_start(void *data, const char *supplied_el, const char **attr) { + HashList *ThisNamespace = NULL; const char *pToken; const char *pch; + const char *NS = NULL; + long NSLen; long len; void *pv; @@ -329,10 +337,61 @@ void xmpp_xml_start(void *data, const char *supplied_el, const char **attr) while (pch != NULL) { pToken = pch; - pch = strchr(pToken, ':'); + pch = strchr(pToken + 1, ':'); } + + if (*pToken == ':') + { + NS = supplied_el; + NSLen = pToken - supplied_el; + if (GetHash(XMPP_NameSpaces, NS, NSLen, &pv)) + { + ThisNamespace = pv; + + } + + pToken ++; + } + len = strlen(pToken); + + if (ThisNamespace != NULL) + { + if (GetHash(ThisNamespace, pToken, len, &pv)) + { + TokenHandler *th; + void *value; + long i = 0; + + th = (TokenHandler*) pv; + value = th->GetToken(); + + while (attr[i] != NULL) + { + + if (GetHash(th->Properties, attr[i], strlen(attr[i]), &pv)) + { + PropertyHandler* ph = pv; + char *val; + StrBuf **pVal; + long len; + + len = strlen(attr[i+1]); + val = value; + val += ph->offset; + pVal = (StrBuf**) val; + if (*pVal != NULL) + StrBufPlain(*pVal, attr[i+1], len); + else + *pVal = NewStrBufPlain(attr[i+1], len); + } + i+=2; + } + return; + } + + } /* XMPP_syslog(LOG_DEBUG, "XMPP ELEMENT START: <%s>\n", el); for (i=0; attr[i] != NULL; i+=2) { @@ -383,14 +442,13 @@ void xmpp_end_iq(void *data, const char *supplied_el, const char **attr) /* * iq type="get" (handle queries) */ - if (!strcasecmp(Xmpp->iq_type, "get")) + if (!strcasecmp(ChrPtr(Xmpp->IQ.type), "get")) { /* * Query on a namespace */ if (!IsEmptyStr(Xmpp->iq_query_xmlns)) { - xmpp_query_namespace(Xmpp->iq_id, Xmpp->iq_from, - Xmpp->iq_to, Xmpp->iq_query_xmlns); + xmpp_query_namespace(&Xmpp->IQ, Xmpp->iq_query_xmlns); } /* @@ -398,18 +456,18 @@ void xmpp_end_iq(void *data, const char *supplied_el, const char **attr) */ else if (Xmpp->ping_requested) { XPUT("iq_from)) { + if (StrLength(Xmpp->IQ.from) > 0) { XPUT("to=\""); - XPutProp(Xmpp->iq_from, strlen(Xmpp->iq_from)); + XPutSProp(Xmpp->IQ.from); XPUT("\" "); } - if (!IsEmptyStr(Xmpp->iq_to)) { + if (StrLength(Xmpp->IQ.to)>0) { XPUT("from=\""); - XPutProp(Xmpp->iq_to, strlen(Xmpp->iq_to)); + XPutSProp(Xmpp->IQ.to); XPUT("\" "); } XPUT("id=\""); - XPutProp(Xmpp->iq_id, strlen(Xmpp->iq_id)); + XPutSProp(Xmpp->IQ.id); XPUT("\"/>"); } @@ -424,7 +482,7 @@ void xmpp_end_iq(void *data, const char *supplied_el, const char **attr) ); */ XPUT("iq_id, strlen(Xmpp->iq_id)); + XPutSProp(Xmpp->IQ.id); XPUT("\">" "" "" @@ -437,12 +495,12 @@ void xmpp_end_iq(void *data, const char *supplied_el, const char **attr) * Non SASL authentication */ else if ( - (!strcasecmp(Xmpp->iq_type, "set")) + (!strcasecmp(ChrPtr(Xmpp->IQ.type), "set")) && (!strcasecmp(Xmpp->iq_query_xmlns, "jabber:iq:auth:query")) ) { xmpp_non_sasl_authenticate( - Xmpp->iq_id, + Xmpp->IQ.id, Xmpp->iq_client_username, Xmpp->iq_client_password, Xmpp->iq_client_resource @@ -454,7 +512,7 @@ void xmpp_end_iq(void *data, const char *supplied_el, const char **attr) */ else if ( (Xmpp->bind_requested) - && (!IsEmptyStr(Xmpp->iq_id)) + && (StrLength(Xmpp->IQ.id)>0) && (!IsEmptyStr(Xmpp->iq_client_resource)) && (CC->logged_in) ) { @@ -470,7 +528,7 @@ void xmpp_end_iq(void *data, const char *supplied_el, const char **attr) /* Tell the client what its JID is */ XPUT("iq_id, strlen(Xmpp->iq_id)); + XPutSProp(Xmpp->IQ.id); XPUT("\">" ""); XPUT(""); @@ -482,26 +540,26 @@ void xmpp_end_iq(void *data, const char *supplied_el, const char **attr) else if (Xmpp->iq_session) { XPUT("iq_id, strlen(Xmpp->iq_id)); + XPutSProp(Xmpp->IQ.id); XPUT("\">" ""); } else { XPUT("iq_id, strlen(Xmpp->iq_id)); + XPutSProp(Xmpp->IQ.id); XPUT("\">"); XPUT("Don't know howto do '"); - XPutBody(Xmpp->iq_type, strlen(Xmpp->iq_type)); + XPutBody(SKEY(Xmpp->IQ.type)); XPUT("'!" ""); } /* Now clear these fields out so they don't get used by a future stanza */ - Xmpp->iq_id[0] = 0; - Xmpp->iq_from[0] = 0; - Xmpp->iq_to[0] = 0; - Xmpp->iq_type[0] = 0; + FlushStrBuf(Xmpp->IQ.id); + FlushStrBuf(Xmpp->IQ.from); + FlushStrBuf(Xmpp->IQ.to); + FlushStrBuf(Xmpp->IQ.type); Xmpp->iq_client_resource[0] = 0; Xmpp->iq_session = 0; Xmpp->iq_query_xmlns[0] = 0; @@ -583,8 +641,12 @@ void xmpp_xml_end(void *data, const char *supplied_el) while (pch != NULL) { pToken = pch; - pch = strchr(pToken, ':'); + pch = strchr(pToken + 1, ':'); } + + if (*pToken == ':') + pToken ++; + len = strlen(pToken); /* @@ -647,6 +709,8 @@ void xmpp_cleanup_function(void) { free(XMPP->message_body); } } + free_buf_iq(&XMPP->IQ); + XML_ParserFree(XMPP->xp); FreeStrBuf(&XMPP->OutBuf); free(XMPP); @@ -776,6 +840,78 @@ void AddXMPPEndHandler(const char *key, Put(XMPP_EndHandlers, key, len, h, NULL); } +void HFreePropertyHandler(void *FreeMe) +{ + free(FreeMe); +} + +void HDeleteTokenHandler(void *FreeMe) +{ + TokenHandler *th = (TokenHandler *) FreeMe; + DeleteHash(&th->Properties); + free(th); +} + +void XMPP_RegisterTokenProperty(const char *NS, long NSLen, + const char *Token, long TLen, + const char *Property, long PLen, + GetTokenDataFunc GetToken, + long offset) +{ + void *pv; + HashList *ThisNamespace = NULL; + PropertyHandler *h; + TokenHandler *th; + + h = (PropertyHandler*) malloc(sizeof(PropertyHandler)); + h->NameSpace = NS; + h->NameSpaceLen = NSLen; + h->Token = Token; + h->TokenLen = TLen; + h->Property = Property; + h->PropertyLen = PLen; + h->offset = offset; + + if (!GetHash(XMPP_SupportedNamespaces, NS, NSLen, &pv)) + { + Put(XMPP_SupportedNamespaces, NS, NSLen, NewStrBufPlain(NS, NSLen), HFreeStrBuf); + } + + + if (GetHash(XMPP_NameSpaces, NS, NSLen, &pv)) + { + ThisNamespace = pv; + } + else + { + ThisNamespace = NewHash(1, NULL); + Put(XMPP_NameSpaces, NS, NSLen, ThisNamespace, HDeleteHash); + } + + if (GetHash(ThisNamespace, Token, TLen, &pv)) + { + th = pv; + } + else + { + th = (TokenHandler*) malloc (sizeof(TokenHandler)); + th->GetToken = GetToken; + th->Properties = NewHash(1, NULL); + Put(ThisNamespace, Token, TLen, th, HDeleteTokenHandler); + } + + Put(th->Properties, Property, PLen, h, HFreePropertyHandler); + /* + if (!GetHash(FlatToken, Token, TLen, &pv)) + { + // todo mark pv as non uniq + Put(FlatToken, Token, TLen, ThisToken, reference_free_handler); + } + */ +} + + + CTDL_MODULE_INIT(xmpp) { if (!threading) { @@ -789,6 +925,9 @@ CTDL_MODULE_INIT(xmpp) XMPP_StartHandlers = NewHash(1, NULL); XMPP_EndHandlers = NewHash(1, NULL); + XMPP_NameSpaces = NewHash(1, NULL); + XMPP_SupportedNamespaces = NewHash(1, NULL); + FlatToken = NewHash(1, NULL); AddXMPPEndHandler(HKEY("resource"), xmpp_end_resource, 0); AddXMPPEndHandler(HKEY("username"), xmpp_end_username, 0); @@ -818,9 +957,10 @@ CTDL_MODULE_INIT(xmpp) CtdlRegisterSessionHook(xmpp_login_hook, EVT_UNSTEALTH, PRIO_UNSTEALTH + 1); CtdlRegisterSessionHook(xmpp_logout_hook, EVT_STEALTH, PRIO_STEALTH + 1); CtdlRegisterCleanupHook(xmpp_cleanup_events); - } /* return our module name for the log */ return "xmpp"; } + + diff --git a/citadel/modules/xmpp/serv_xmpp.h b/citadel/modules/xmpp/serv_xmpp.h index 715abd41d..2137ea330 100644 --- a/citadel/modules/xmpp/serv_xmpp.h +++ b/citadel/modules/xmpp/serv_xmpp.h @@ -16,6 +16,10 @@ * */ +#include "xmpp_xmacros.h" +#include "xmpp_util.h" + + typedef struct _citxmpp { /* Information about the current session */ StrBuf *OutBuf; XML_Parser xp; /* XML parser instance for incoming client stream */ @@ -26,10 +30,8 @@ typedef struct _citxmpp { /* Information about the current session */ char client_jid[256]; /* "full JID" of the client */ int last_event_processed; - char iq_type[256]; /* for stanzas */ - char iq_id[256]; - char iq_from[256]; - char iq_to[256]; + TheToken_iq IQ; + char iq_client_username[256]; /* username requested by the client (NON SASL ONLY) */ char iq_client_password[256]; /* password requested by the client (NON SASL ONLY) */ char iq_client_resource[256]; /* resource name requested by the client */ @@ -80,14 +82,14 @@ void xmpp_command_loop(void); void xmpp_async_loop(void); void xmpp_sasl_auth(char *, char *); void xmpp_output_auth_mechs(void); -void xmpp_query_namespace(char *, char *, char *, char *); +void xmpp_query_namespace(TheToken_iq *iq, char *); void xmpp_output_incoming_messages(void); void xmpp_queue_event(int, char *); void xmpp_process_events(void); void xmpp_presence_notify(char *, int); void xmpp_roster_item(struct CitContext *); void xmpp_send_message(char *, char *); -void xmpp_non_sasl_authenticate(char *, char *, char *, char *); +void xmpp_non_sasl_authenticate(StrBuf *IQ_id, char *, char *, char *); void xmpp_massacre_roster(void); void xmpp_delete_old_buddies_who_no_longer_exist_from_the_client_roster(void); int xmpp_is_visible(struct CitContext *from, struct CitContext *to_whom); @@ -106,15 +108,6 @@ extern int XMPPSrvDebugEnable; "XMPP: " FORMAT); -void XUnbuffer(void); -void XPutBody(const char *Str, long Len); -void XPutProp(const char *Str, long Len); -void XPut(const char *Str, long Len); -#define XPUT(CONSTSTR) XPut(CONSTSTR, sizeof(CONSTSTR) -1) - -void XPrintf(const char *Format, ...); - - void AddXMPPStartHandler(const char *key, long len, xmpp_handler_func Handler, @@ -126,19 +119,5 @@ void AddXMPPEndHandler(const char *key, 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 + + diff --git a/citadel/modules/xmpp/token.def b/citadel/modules/xmpp/token.def new file mode 100644 index 000000000..6799c8dc2 --- /dev/null +++ b/citadel/modules/xmpp/token.def @@ -0,0 +1,20 @@ + +#define NAMESPACE_iq "jabber:client" +TOKEN(iq, + { + STRPROP(iq, type); + STRPROP(iq, id); + STRPROP(iq, from); + STRPROP(iq, to); + }) + + +#define NAMESPACE_piq "bub" + +TOKEN(piq, + { + STRPROP(piq, type); + STRPROP(piq, id); + STRPROP(piq, from); + STRPROP(piq, to); + }) diff --git a/citadel/modules/xmpp/xmpp_query_namespace.c b/citadel/modules/xmpp/xmpp_query_namespace.c index 0da671c5f..8bb9b442b 100644 --- a/citadel/modules/xmpp/xmpp_query_namespace.c +++ b/citadel/modules/xmpp/xmpp_query_namespace.c @@ -112,7 +112,7 @@ xmpp_query_namespace(purple5b5c1e5a, , vcard-temp:query) * */ -void xmpp_query_namespace(char *iq_id, char *iq_from, char *iq_to, char *query_xmlns) +void xmpp_query_namespace(TheToken_iq *IQ/*char *iq_id, char *iq_from, char *iq_to*/, char *query_xmlns) { int supported_namespace = 0; int roster_query = 0; @@ -134,7 +134,7 @@ void xmpp_query_namespace(char *iq_id, char *iq_from, char *iq_to, char *query_x supported_namespace = 1; } - XMPP_syslog(LOG_DEBUG, "xmpp_query_namespace(%s, %s, %s, %s)\n", iq_id, iq_from, iq_to, query_xmlns); + XMPP_syslog(LOG_DEBUG, "xmpp_query_namespace(%s, %s, %s, %s)\n", ChrPtr(IQ->id), ChrPtr(IQ->from), ChrPtr(IQ->to), query_xmlns); /* * Beginning of query result. @@ -150,8 +150,8 @@ void xmpp_query_namespace(char *iq_id, char *iq_from, char *iq_to, char *query_x XPrint(HKEY("iq"), 0, XPROPERTY("type", TypeStr, TLen), - XOPROPERTY("to", iq_from, strlen(iq_from)), - XPROPERTY("id", iq_id, strlen(iq_id))); + XSPROPERTY("to", IQ->from), + XSPROPERTY("id", IQ->id)); /* * Is this a query we know how to handle? diff --git a/citadel/modules/xmpp/xmpp_sasl_service.c b/citadel/modules/xmpp/xmpp_sasl_service.c index fd4986137..ba6dba137 100644 --- a/citadel/modules/xmpp/xmpp_sasl_service.c +++ b/citadel/modules/xmpp/xmpp_sasl_service.c @@ -154,7 +154,7 @@ void xmpp_sasl_auth(char *sasl_auth_mech, char *authstring) { /* * Non-SASL authentication */ -void xmpp_non_sasl_authenticate(char *iq_id, char *username, char *password, char *resource) { +void xmpp_non_sasl_authenticate(StrBuf *IQ_id, char *username, char *password, char *resource) { int result; if (CC->logged_in) CtdlUserLogout(); /* Client may try to log in twice. Handle this. */ @@ -165,7 +165,7 @@ void xmpp_non_sasl_authenticate(char *iq_id, char *username, char *password, cha if (result == pass_ok) { XPrint(HKEY("iq"), XCLOSED, XCPROPERTY("type", "result"), - XPROPERTY("ID", iq_id, strlen(iq_id)), + XSPROPERTY("ID", IQ_id), TYPE_ARGEND); /* success */ return; @@ -175,7 +175,7 @@ void xmpp_non_sasl_authenticate(char *iq_id, char *username, char *password, cha /* failure */ XPrint(HKEY("iq"), 0, XCPROPERTY("type", "error"), - XPROPERTY("ID", iq_id, strlen(iq_id)), + XSPROPERTY("ID", IQ_id), TYPE_ARGEND); XPUT("" "" diff --git a/citadel/modules/xmpp/xmpp_util.h b/citadel/modules/xmpp/xmpp_util.h new file mode 100644 index 000000000..1485c77a2 --- /dev/null +++ b/citadel/modules/xmpp/xmpp_util.h @@ -0,0 +1,49 @@ +typedef void* (*GetTokenDataFunc)(void); + +typedef struct __TokenHandler { + HashList *Properties; + GetTokenDataFunc GetToken; +}TokenHandler; + +typedef struct __PropertyHandler { + const char *NameSpace; + long NameSpaceLen; + const char *Token; + long TokenLen; + const char *Property; + long PropertyLen; + long offset; +} PropertyHandler; + +void XUnbuffer(void); +void XPutBody(const char *Str, long Len); +void XPutProp(const char *Str, long Len); +#define XPutSProp(STR) XPutProp(ChrPtr(STR), StrLength(STR)) +void XPut(const char *Str, long Len); +#define XPUT(CONSTSTR) XPut(CONSTSTR, sizeof(CONSTSTR) -1) + +void XPrintf(const char *Format, ...); + +#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 XSPROPERTY(NAME, VALUE) TYPE_STR, NAME, sizeof(NAME)-1, ChrPtr(VALUE), StrLength(VALUE) +#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 + +void XMPP_RegisterTokenProperty(const char *NS, long NSLen, + const char *Token, long TLen, + const char *Property, long PLen, + GetTokenDataFunc GetToken, + long offset); diff --git a/citadel/modules/xmpp/xmpp_xmacros.c b/citadel/modules/xmpp/xmpp_xmacros.c new file mode 100644 index 000000000..3366cbcfc --- /dev/null +++ b/citadel/modules/xmpp/xmpp_xmacros.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include "ctdl_module.h" +#include "serv_xmpp.h" + +void *GetToken_iq(void) +{ + return &XMPP->IQ; +} +void *GetToken_piq(void) +{ + return NULL; +} + + +#define STRPROP(STRUCTNAME, NAME) \ + if (StrLength(pdata->NAME) > 0) \ + { \ + XPut(#NAME, sizeof(#NAME) - 1); \ + XPut("=\"", 2); \ + XPutProp(SKEY(pdata->NAME)); \ + XPut("\" ", 2); \ + } + +#define THENAMESPACE(STRUCTNAME, NAME) \ + XPut(#NAME, sizeof(#NAME) - 1); \ + XPut("=\"", 2); \ + XPutProp(NAMESPACE_##STRUCTNAME, \ + sizeof(NAMESPACE_##STRUCTNAME)-1); \ + XPut("\" ", 2); + +#define TOKEN(NAME, STRUCT) \ + void serialize_##NAME(TheToken_##NAME *pdata, int Close) \ + { \ + XPUT("<"); \ + XPut(#NAME, sizeof(#NAME)); \ + XPUT(" "); \ + STRUCT ; \ + XPUT(">"); \ + if (Close) \ + { \ + XPut("", 1); \ + } \ + } + +#include "token.def" +#undef STRPROP +#undef TOKEN + + +#define STRPROP(STRUCTNAME, NAME) \ + FreeStrBuf(&pdata->NAME); + +#define TOKEN(NAME, STRUCT) \ + void free_buf_##NAME(TheToken_##NAME *pdata) \ + { \ + STRUCT ; \ + } + +#include "token.def" +#undef STRPROP +#undef TOKEN + +#define TOKEN(NAME, STRUCT) \ + void free_##NAME(TheToken_##NAME *pdata) \ + { \ + free_buf_##NAME(pdata); \ + free(pdata); \ + } + +#include "token.def" +#undef STRPROP +#undef TOKEN + + + +CTDL_MODULE_INIT(xmpp_xmacros) +{ + if (!threading) { +#define STRPROP(TOKENNAME, PROPERTYNAME) \ + long offset##PROPERTYNAME = \ + offsetof(TheToken_##TOKENNAME, PROPERTYNAME); \ + XMPP_RegisterTokenProperty( \ + NAMESPACE_##TOKENNAME, \ + sizeof(NAMESPACE_##TOKENNAME)-1, \ + #TOKENNAME, sizeof(#TOKENNAME)-1, \ + #PROPERTYNAME, sizeof(#PROPERTYNAME)-1, \ + GetToken_##TOKENNAME, \ + offset##PROPERTYNAME); +#define TOKEN(NAME, STRUCT) STRUCT +#include "token.def" +#undef STRPROP +#undef TOKEN + } + + /* return our module name for the log */ + return "xmpp_xmacros"; +} diff --git a/citadel/modules/xmpp/xmpp_xmacros.h b/citadel/modules/xmpp/xmpp_xmacros.h new file mode 100644 index 000000000..3d5d94d53 --- /dev/null +++ b/citadel/modules/xmpp/xmpp_xmacros.h @@ -0,0 +1,35 @@ + +/* + * define the structures for one token each + * typename: TheToken_ + */ +#define STRPROP(STRUCTNAME, NAME) StrBuf *NAME; +#define TOKEN(NAME, STRUCT) typedef struct __##NAME \ + STRUCT \ + TheToken_##NAME; +#include "token.def" +#undef STRPROP +#undef TOKEN + + +/* + * forward declarations for freeing the members of one struct instance + # name: free_buf_ + */ + +#define TOKEN(NAME, STRUCT) \ + void free_buf_##NAME(TheToken_##NAME *pdata); +#include "token.def" +#undef STRPROP +#undef TOKEN + +/* + * forward declarations, freeing structs and member. + * name: free_ + */ +#define TOKEN(NAME, STRUCT) \ + void free_##NAME(TheToken_##NAME *pdata); + +#include "token.def" +#undef STRPROP +#undef TOKEN -- 2.30.2