[prev in list] [next in list] [prev in thread] [next in thread] 

List:       jabber-jdev
Subject:    [JDEV] hack to make transports work with xdb_sql
From:       raditha dissanayake <jabber () raditha ! com>
Date:       2002-10-24 14:13:09
[Download RAW message or body]

hi guys,

We've been having posts on and off about using xdb_sql with transports. 
Here is a plain old hack to
make xdb_sql work with transports other than yahoo. Most of it is 
inspired by the yahoo transport
and the example works with icqv7t 0.3.0 (great work alex)



1. Let's start off by creating the table in mysql


    CREATE TABLE icq (
      username VARCHAR(32) PRIMARY KEY,
      icq_id    VARCHAR(32) NOT NULL,
      icq_pass  VARCHAR(32) NOT NULL
    );



2. then you need to create the query defs in xdb_sql.xml try adding the 
following island. Since
we are using v2 queries we don't need to code any validation functions



<!-- icq set query -->
      <querydef name="icq-set" dtd="2" type="set" namespace="icqtrans:data">
    <text>
     INSERT INTO icq VALUES ('$$user$$', '$$id$$', '$$pass$$')
     </text>

    <user>$$user$$</user>
        <bindvar attrib="id">$$id$$</bindvar>
        <bindvar attrib="pass">$$pass$$</bindvar>
    <purge>icq-remove</purge>
      </querydef>

<!-- icq removal query -->
      <querydef name="icq-remove" dtd="2" type="remove" 
namespace="icqtrans:data">
        <text>
      DELETE FROM icq where username='$$user$$'
       </text>
        <user>$$user$$</user>
      </querydef>

<!-- icq get query -->
      <querydef name="icq-get" dtd="2" type="get" namespace="icqtrans:data">
    <text>
     SELECT icq_id, icq_pass  FROM icq WHERE username = '$$user$$'
     </text>

    <user>$$user$$</user>
        <top-result>
           <logon/>
        </top-result>
        <bindcol attrib="username" offset="0"/>
    <bindcol attrib="password" offset="1"/>
      </querydef>


3. Then you need to make changes to the actual code. Since it would be 
nice if the transport continued
to work with xdb_file i have used an #ifdef, so that means you will need 
to add a -Dsql to your makefile
if you want to use it with xdb_sql.

The actual changes are to jabberd/utils.c and jabbered/unknown.c. The 
two files are attached. Please compare
them with the original. Couple of new functions have been added to utils 
c while unknown.c gets a few
lines of code inserted.

4. make the transport and restart it.


all the best





["utils.c" (text/plain)]

/* --------------------------------------------------------------------------
 *
 * License
 *
 * The contents of this file are subject to the Jabber Open Source License
 * Version 1.0 (the "License").  You may not copy or use this file, in either
 * source code or executable form, except in compliance with the License.  You
 * may obtain a copy of the License at http://www.jabber.com/license/ or at
 * http://www.opensource.org/.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Copyright (c) 1999-2000 Schuyler Heath <sheath@jabber.org>
 *
 * Acknowledgements
 *
 * Special thanks to the Jabber Open Source Contributors for their
 * suggestions and support of Jabber.
 *
 * utils.c - common utils and functions that don't belong anywhere else
 * --------------------------------------------------------------------------*/

/*
 * Added modifications for ICQv7-t project (icqv7-t.sf.net) by
 *  - Alexandre N. Safiullin
 *
 * Coryright (c) 2001      Alexandre N. Safiullin <alex_@unis-ru.com>
 */

#include "icqtransport.h"
/* #include "tables.h" */

/* int it_bigendian; */

/* void it_check_endian(void) */
/* { */
/*     int i; */
/*     char passwd[10]; */

/*     passwd[0] = 1; */
/*     passwd[1] = 0; */
/*     passwd[2] = 0; */
/*     passwd[3] = 0; */
/*     passwd[4] = 0; */
/*     passwd[5] = 0; */
/*     passwd[6] = 0; */
/*     passwd[7] = 0; */
/*     passwd[8] = 0; */
/*     passwd[9] = 0; */

/*     i = *(icqlong *) passwd; */
/*     if (i == 1) */
/*     { */
/*         log_debug(ZONE,"Little endian"); */
/*         it_bigendian = 0; */
/*     } */
/*     else */
/*     { */
/*         log_debug(ZONE,"Big endian"); */
/*         it_bigendian = 1; */
/*     } */

    /* initialize random */
/*     srandom(time(NULL)); */
/* } */

jid it_xdb_id(pool p, jid id, char *server)
{
    return jid_new(p,spools(p,id->user,"%",id->server,"@",server,p));
}

UIN_t it_strtouin(char *uin)
{
    return uin != NULL ? strtoul(uin,NULL,10): 0;
}

jid it_uin2jid(pool p, UIN_t uin, char *server)
{
    jid id;
    char buffer[16];

    id = (jid) pmalloco(p,sizeof(struct jid_struct));

    id->p = p;
    id->server = pstrdup(p,server);
    snprintf(buffer,16,"%lu",uin);
    id->user = pstrdup(p,buffer);

    return id;
}

icqstatus it_show2status(const char *show)
{
    if (show == NULL)
        return STATUS_ONLINE;

    if (j_strcmp(show,"away")==0)
        return STATUS_AWAY;
    if (j_strcmp(show,"busy")==0)
        return STATUS_OCCUPIED;
    if (j_strcmp(show,"chat")==0)
        return STATUS_FREE_CHAT;
    if (j_strcmp(show,"dnd")==0)
        return STATUS_DND;
    if (j_strcmp(show,"xa")==0)
        return STATUS_NA;

    return STATUS_ONLINE;
}

char *it_strrepl(pool p, const char *orig, const char *find, const char
*replace)
{
    const char *loc;
    char *newstr, *temp, *tempstr;
    unsigned int olen, flen, rlen, i;

    if (!orig || !find || !replace || !p)
        return NULL;  /* oops */

    olen = strlen(orig);
    flen = strlen(find);
    rlen = strlen(replace);

    temp = strstr(orig,find);
    if (!temp)
        return pstrdup(p,orig);

    /* count up any instances of the string we can find */
    i = 0;
    while (temp)
    { /* advance past current instance and get a count */
        temp += flen;
        i++;
        temp = strstr(temp,find);
    }

    /* allocate a buffer for the new string */
    newstr = pmalloc(p,(olen + ((rlen - flen) * i) + 1) * sizeof(char));
    tempstr = newstr;
    loc = orig;

    while((temp = strstr(loc,find))!=NULL)
    { /* copy pieces into the new buffer */
        memcpy(tempstr,loc,(int)(temp - loc));
        tempstr += (int)(temp - loc);

        memcpy(tempstr,replace,rlen);
        tempstr += rlen;

        loc = temp + flen;
    }

    strcpy(tempstr,loc);  /* copy the last piece */

    return newstr;
}

void it_delay(xmlnode x, char *ts)
{
    xmlnode delay;

    delay = xmlnode_insert_tag(x,"x");
    xmlnode_put_attrib(delay,"xmlns",NS_DELAY);
    xmlnode_put_attrib(delay,"from",xmlnode_get_attrib(x,"to"));
    xmlnode_put_attrib(delay,"stamp",ts);
}

int it_reg_set(session s, xmlnode reg)
{
    iti ti = s->ti;
    jid id;
    xmlnode x;
    pool p;
//    char uin[16];

    p = xmlnode_pool(reg);
    while ((x = xmlnode_get_tag(reg,"key")) != NULL) xmlnode_hide(x);
    xmlnode_hide(xmlnode_get_tag(reg,"instructions"));
//    xmlnode_hide(xmlnode_get_tag(reg,"username"));
//    snprintf(uin,16,"%lu",s->uin);
//    xmlnode_insert_cdata(xmlnode_insert_tag(reg,"username"),uin,-1);

    id = it_xdb_id(p,s->id,s->from->server);
    if (xdb_set(ti->xc,id,NS_REGISTER,reg))
    {
        log_error(ZONE,"Failed to updated register settings");
        return 1;
    }

    return 0;
}

jid jid_canonize(jid a)
{
    jid ret;

    if(a == NULL) return a;

    ret = pmalloco(a->p,sizeof(struct jid_struct));
    ret->p = a->p;
    ret->user = a->user;
    ret->server = a->server;

    return ret;
}


/**
 * i have created this function based on the similar function in the
 * yahoo transport
 */

int icq_xdb_set(iti ti, char *host, jid owner, xmlnode data)
{
    int ret;
    jid j;
    char *res;


    res = owner->resource;

    jid_set(owner, NULL, JID_RESOURCE);

    //j = jid_new(owner->p, spools(owner->p, shahash(jid_full(owner)), "@", host, owner->p));
    ret = xdb_act(ti->xc, owner, "icqtrans:data", "insert", "logon", data);

    log_error(ZONE,"the icq query is %s", xmlnode2str(data));
    xmlnode_free(data);

    jid_set(owner, res, JID_RESOURCE);

    return ret;
}


/**
 * this function is based on the similar function that exists in yahoo trans.
 */

xmlnode icq_xdb_get(iti ti, char *host, jid owner, jpacket jp)
{
    xmlnode x, query;

    jid j;
    char *res;


    res = owner->resource;
    jid_set(owner, NULL, JID_RESOURCE);

    query =xmlnode_new_tag("query");
    xmlnode_put_attrib(query,"xmlns","jabber:iq:register");


    x = xdb_get(ti->xc, owner, "icqtrans:data");


    xmlnode_insert_tag_node(query,xmlnode_get_tag(x,"username"));
    xmlnode_insert_tag_node(query,xmlnode_get_tag(x,"password"));

    jid_set(owner, res, JID_RESOURCE);

    log_error(ZONE,"this is part of the icq_xdb_sql %s %s\n", host,
    xmlnode2str(query));
    return query;
}



["unkown.c" (text/plain)]

/* --------------------------------------------------------------------------
 *
 * License
 *
 * The contents of this file are subject to the Jabber Open Source License
 * Version 1.0 (the "License").  You may not copy or use this file, in either
 * source code or executable form, except in compliance with the License.  You
 * may obtain a copy of the License at http://www.jabber.com/license/ or at
 * http://www.opensource.org/.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Copyright (c) 1999-2000 Schuyler Heath <sheath@jabber.org>
 *
 * Acknowledgements
 *
 * Special thanks to the Jabber Open Source Contributors for their
 * suggestions and support of Jabber.
 *
 * unknown.c - handles packets from users without a session, starts sessions
 * --------------------------------------------------------------------------*/

/*
 * Added modifications for ICQv7-t project (icqv7-t.sf.net) by
 *  - Alexandre N. Safiullin
 *
 * Coryright (c) 2001      Alexandre N. Safiullin <alex_@unis-ru.com>
 */

#include "icqtransport.h"
#include <sys/utsname.h>

void it_unknown_iq(iti ti, jpacket jp);
void it_unknown_presence(void *arg);
void it_unknown_reg_get(iti ti, jpacket jp);
void it_unknown_reg_set(iti ti, jpacket jp);

void it_unknown(iti ti, jpacket jp) {

	log_error("debug","it_unknown");
    switch (jp->type) {
    case JPACKET_IQ:
		it_unknown_iq(ti,jp);
		break;

    case JPACKET_MESSAGE:
    case JPACKET_S10N:
        jp->aux1 = (void *) ti;
        mtq_send(NULL,jp->p,it_unknown_bounce,(void *) jp);
        break;

    case JPACKET_PRESENCE:
        if ((jpacket_subtype(jp) == JPACKET__AVAILABLE ||
			 jpacket_subtype(jp) == JPACKET__INVISIBLE)
			&& jp->to->user == NULL ) {

            jp->aux1 = (void *) ti;
            mtq_send(NULL,jp->p,it_unknown_presence,(void *) jp);
            break;
        }
    default:
        xmlnode_free(jp->x);
    }
}

void it_unknown_iq(iti ti, jpacket jp)
{
    char *ns;

    if (jp->to->user != NULL)
    {
        jp->aux1 = (void *) ti;
        mtq_send(NULL,jp->p,it_unknown_bounce,(void *) jp);
        return;
    }

    ns = xmlnode_get_attrib(jp->iq,"xmlns");

    switch (jpacket_subtype(jp))
    {
    case JPACKET__SET:
        if (j_strcmp(ns,NS_REGISTER) == 0)
            it_unknown_reg_set(ti,jp);
        else
        {
            jutil_error(jp->x,TERROR_NOTALLOWED);
            it_deliver(ti,jp->x);
        }
        break;

    case JPACKET__GET:
        if (j_strcmp(ns,NS_REGISTER) == 0)
            it_unknown_reg_get(ti,jp);
        else if (j_strcmp(ns,NS_BROWSE) == 0)
            it_iq_browse_server(ti,jp);
        else if (j_strcmp(ns,NS_VERSION) == 0)
            it_iq_version(ti,jp);
        else if (j_strcmp(ns,NS_TIME) == 0)
            it_iq_time(ti,jp);
        else if (j_strcmp(ns,NS_VCARD) == 0)
            it_iq_vcard_server(ti,jp);
        else if (j_strcmp(ns,NS_LAST) == 0)
            jp->to->user == NULL ? it_iq_last(ti,jp) : xmlnode_free(jp->x);
/*         else if (j_strcmp(ns,NS_ADMIN) == 0) */
/*             it_iq_admin(ti,jp); */
        else
        {
            jutil_error(jp->x,TERROR_NOTALLOWED);
            it_deliver(ti,jp->x);
        }
        break;

    default:
        jutil_error(jp->x,TERROR_NOTALLOWED);
        it_deliver(ti,jp->x);
    }
}

void it_unknown_presence(void *arg)
{
    jpacket jp = (jpacket) arg;
    iti ti = (iti) jp->aux1;
    xmlnode reg,x;
    session s;
	jpq jq;



#ifdef sql
    reg = icq_xdb_get(ti, jp->to->server, jp->from, jp);
    log_debug(ZONE,"%s, %s",xmlnode2str(reg), jp->from->full);
#else
    reg = xdb_get(ti->xc,it_xdb_id(jp->p,jp->from,jp->to->server),NS_REGISTER);
#endif

    if (reg == NULL)
    {
        log_debug(ZONE,"Registration not found for %s",jid_full(jp->from));
        xmlnode_free(jp->x);
        return;
    }

	s = (session) xhash_get(ti->sessions,jid_full(jid_user(jp->from)));
    if (s != NULL)
    {
        log_debug(ZONE,"Session %s already created",jid_full(jp->from));
        jp->aux1 = (void *) s;
        mtq_send(s->q,jp->p,it_session_jpacket,(void *) jp);
        xmlnode_free(reg);
        return;
    }

    s = it_session_create(ti,jp);
    s->type = stype_normal;
    s->uin = it_strtouin(xmlnode_get_tag_data(reg,"username"));

    /* update users presence */
    s->p_db = ppdb_insert(s->p_db,jp->from,jp->x);

	if(jpacket_subtype(jp)==JPACKET__AVAILABLE){
		x=jutil_iqnew(JPACKET__SET,NS_REGISTER);
		xmlnode_put_attrib(x,"from",jid_full(jp->from));
		xmlnode_hide(xmlnode_get_tag(x,"query"));
		xmlnode_insert_node(x,reg);
		log_error("debug","trying to log in using existing registration: %s\n",
				  xmlnode2str(x));

		xmlnode_free(reg);
		it_retransmit(ti,x);

		it_contact_load_roster(s);
	}
	else /* INVISIBLE -> external back end should be connected */
		it_retransmit(ti,xmlnode_dup(jp->x));

	jq = pmalloco(jp->p,sizeof(_jpq)); /* save packet to handle it when
confirmation
										  will be received */
	jq->jp = jp;
	pth_msgport_put(s->queue,(pth_message_t *)jq);
	return;

}

void it_unknown_reg_get(iti ti, jpacket jp)
{
    xmlnode q;

    if (ti->reg_inst)
    {
        jutil_iqresult(jp->x);
        q = xmlnode_insert_tag(jp->x,"query");
        xmlnode_put_attrib(q,"xmlns",NS_REGISTER);

        xmlnode_insert_tag(q,"username");
        xmlnode_insert_tag(q,"nick");
        xmlnode_insert_tag(q,"first");
        xmlnode_insert_tag(q,"last");
        xmlnode_insert_tag(q,"email");
        xmlnode_insert_tag(q,"password");


xmlnode_insert_cdata(xmlnode_insert_tag(q,"instructions"),ti->reg_inst,-1);

xmlnode_insert_cdata(xmlnode_insert_tag(q,"key"),jutil_regkey(NULL,jid_full(jp->from)),-1);
    }
    else
        jutil_error(jp->x,TERROR_NOTALLOWED);

    it_deliver(ti,jp->x);
}

void it_unknown_reg_set(iti ti, jpacket jp)
{
    session s;
    xmlnode q = jp->iq;
    UIN_t uin;
    jpq jq;
    char *user, *pass;
	xmlnode logon;

    if (ti->reg_inst == NULL)
    {
        jutil_error(jp->x,TERROR_NOTALLOWED);
        it_deliver(ti,jp->x);
        return;
    }

    pass = xmlnode_get_tag_data(q,"password");
    user = xmlnode_get_tag_data(q,"username");
	if(!user || !pass)
    {
        jutil_error(jp->x,TERROR_NOTACCEPTABLE);
        it_deliver(ti,jp->x);
        return;
    }

    uin = it_strtouin(user);
    if (uin == 0)
    {
        jutil_error(jp->x,TERROR_NOTACCEPTABLE);
        it_deliver(ti,jp->x);
        return;
    }

#ifdef sql
	logon = xmlnode_new_tag("logon");
    xmlnode_put_attrib(logon, "id", user);
    xmlnode_put_attrib(logon, "pass",pass);
	log_error(ZONE,"%s",xmlnode2str(logon));
	icq_xdb_set(ti, jp->from->server,jp->from, logon);
#endif

    s = it_session_create(ti,jp);
    s->type = stype_register;
    s->uin = uin;

    jq = pmalloco(jp->p,sizeof(_jpq));
    jq->jp = jp;
    pth_msgport_put(s->queue,(pth_message_t *)jq);
	it_retransmit(ti,xmlnode_dup(jp->x));
}

void it_unknown_bounce(void *arg)
{
    jpacket jp = (jpacket) arg;
    iti ti = (iti) jp->aux1;
    xmlnode reg;

    reg = xdb_get(ti->xc,it_xdb_id(jp->p,jp->from,jp->to->server),NS_REGISTER);
    if (reg != NULL)
    {
        jutil_error(jp->x,(terror){404,"Session Not Found"});
        xmlnode_free(reg);
    }
    else
        jutil_error(jp->x,TERROR_REGISTER);

    it_deliver(ti,jp->x);
}


_______________________________________________
jdev mailing list
jdev@jabber.org
http://mailman.jabber.org/listinfo/jdev

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic